Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Взаимодействие потоков


Автор: jonie 24.7.2007, 00:33
итак, возникла незначительная проблема с выбором метода...
имеется : головной модуль - окно с менюшкой. грузит субмодули. Каждый субмодуль может при регистрировании добавить к окошку головного модуля свою субменюшку. И каждый субмодуль стартует свою Thread обработки чего-то (окон не имеет своих).
Вопросы : 
1)как обеспечить взаимодействие "сверху вниз" (по щелчку на менюшке, зарегиной субмодулем, чтобы этот субмодуль реагировал)
2)как обеспечить взаимодействие "снизу-вверх" (чтобы головной модуль мог реагировать на ситуации в субмодулях)..

Если с (2) еще более-менее понятно  (PostMessage (?) ) , то вот с первым чет не очень...

Дополнительные условия: 
1)в субмодулях окон нет
2)"тормозить" головной модуль крайне нежелательно
3)когда произойдет обработка события в субмодуле и как долго она будет идти неизветно (т.е. вызов просто CALLBACK субмодуля не очень подходит)....


Пока из вариантов пришел к одному:
1)субмодуль регистрирует Event-ы , которые ассоциируеются в головном модуле с менюшками.
2)при шелчке голвной модуль ставит event
3)субмодуль ожидает в своей ветке WaitForMultiplyEvents() и позже выбирает какой эвен стоит (если вообще стоит). Кстати, как такое грамотно реализуется (выбор что стоит)?

мб кто че расскажет про PostThreadMessage ? Чет мне думается это лучше чем Wait* функции? (ожидается что субмодули будут некторое время "спать", регулярно)...

Пните чтоли в какую сторону лететь или как такие вещи грамотно делаются...

Автор: takedo 24.7.2007, 07:53
по моему с эвентами нормально

Автор: Earnest 24.7.2007, 20:33
Цитата(jonie @  24.7.2007,  01:33 Найти цитируемый пост)
про PostThreadMessage 

для рабочих потоков не годится: нужен цикл обработки сообщений.

Я бы регистрировала при добавлении менюшек не ивенты (как-то это слишком), а указатели объекты-агенты с заданным интерфейсом (virtual void OnCommand (UINT ID)), которым бы посылала команды, выбранные из меню.
Требования по быстрой обработке (т.е. быстрому возврату из OnCommand) я бы повесила на суб-модули (скажем, запустим поток и быстренько вернемся). А может, что-то совсем простое нужно сделать.
Кроме прочего, такой подход позволяет добавить агенту функцию OnUpdate, чтобы обновлять пункты меню согласно текущей ситуации, что часто не лишне.

Обрабтная связь (от суб-модуля к главному) - через сообщения, можно и через PostThreadMessage, но проще посылать главному окну.
А ивенты и прочая синхронизация - пусть будут локальными в каждом субмодуле (что, конечно, не исключает использования общего базового кода).

Добавлено через 3 минуты и 46 секунд
При таком подходе суб-модуль может стартовать поток сразу после регистрации и ждать чего-то (что выставит соответсвующий OnCommand в главном потоке) или запускать поток для каждой новой команды, в зависимости от выполняемых задач. И насчет обновления: скажем, пока обсчитывается какая-то задача (поток работает) можно дизэблить соответсвующую команду, что выглядит вполне разумно. 

Автор: jonie 24.7.2007, 22:23
Цитата

Я бы регистрировала при добавлении менюшек не ивенты (как-то это слишком), а указатели объекты-агенты..
кто их создает немного непонял(...
если создать их во время регистрации субмодуля то они окажутся в главном потоке созданы (поток субмодуля еще не создан), проблема взаимодействия их с потоком субмодуля останется, разве нет?
А если в потоке субмодуля (скажем при его запуске) то непонятно как взаимодействовать с этими агентами, когда поток субмодуля занят обработкой.. или я что-то недопонимаю.

Цитата

И насчет обновления: скажем, пока обсчитывается какая-то задача (поток работает) можно дизэблить соответсвующую команду, что выглядит вполне разумно. 
не.. для моей задачи неразумно как раз.. функции должны быть доступны для вызова из этих менюшек, а вот когда они будут выполнены уже не так критично... главное что они будут выполнены)....

Цитата

для рабочих потоков не годится: нужен цикл обработки сообщений.
блокируется поток при ожидании сообщения потокового или как-то можно установить макс время ожидания сообщения (как скажем для функций Wait*) ?....просвятите плс...

Просто хотелось бы иметь очередь "что предназначено субмодулю".. можно, конечно, заносить в свою в главном потоке.... но тут вроде как системная , готовая)....

Автор: Pulse69 25.7.2007, 01:20
Цитата(jonie @  24.7.2007,  22:23 Найти цитируемый пост)
кто их создает немного непонял(...если создать их во время регистрации субмодуля то они окажутся в главном потоке созданы (поток субмодуля еще не создан), проблема взаимодействия их с потоком субмодуля останется, разве нет?

Такой интерфейс должен создаваться субмодулем. Главный модуль будет знать только набор виртуальных методов, а их реализация ляжет на субмодули. 
К примеру, создаётся такой класс

Код

class IPlugin
{
public: virtual void onCommand( UINT CommandID ) = 0;
};



Его описание будет доступно в главном модуле и в субмодуле.
Теперь в субмодуле пишется производный класс
Код

class Plugin: public IPlugin
{
public: 
    Plugin( void* params )
    {
    }

    virtual void onCommand( UINT CommandID )
    {
    }
};


В субмодуле будет функция типа
Код

IPlugin* InitializeModule( void* params )
{
     return dynamic_cast<IPlugin*>( new Plugin( params ) );
}


которая создаст экземпляр реализующего класса.

Сама реализация функции onCommand не должна занимать много времени, как уже сказала Earnest.
Например, класс Plugin после создание (в конструкторе) запускает поток и регистрирует внутренний Event для сообщений этому потоку, а реализация onCommand просто сохраняет ID команды и выставляет этот Event.

Автор: Earnest 25.7.2007, 05:56
Да, Pulse69 все верно написал. Объект создает суб-модуль, конечно, ибо только он знает его истинную реализацию, и в главном потоке. И неважно, в каком потоке что создано. Если нужно синхронизировать доступ к каким-то данным, то есть простые средства вроде критической секции. 

Для того, чтобы иметь в субмодуле очередь, нужно создавать интерфейсный поток с очередьюсообщений. Рабочий поток, где просто функция крутится, такой очередью не обладает. Ну нечем ему сообщения принимать. Он целиком состоит из той функции, которую ты передал во время создания потока, и другого кода там, считай, нет.

Ну раз не надо тебе дизэблить менюшки, так и ладно. Значит, получается, что надо обеспечить возможность запуска второго потока на обсчет хотя первый еще не закончил. Т.е. субмодуль должен состоять из кода, работающего в главном потоке (получающего команды меню, тот самый OnCommand)  и управляющего созданными потоками, и самих потоков.

Автор: Debugg3R 25.7.2007, 07:17
Можно использовать механизм типа "Семафор". А для передачи данных  "Канал"

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)