#c #multithreading
#c #многопоточность
Вопрос:
У меня есть приложение на C , которое имеет следующую структуру:
Класс AAA: имеет несколько функций, и одна из них функция, которая открывает поток. Класс BBB: имеет несколько функций, и одна из них функция, которая открывает поток. Класс CCC: вызовите AAA и BBB, чтобы оба внутренних в своих функциях открывали дорожки.
В потоке AAA в некоторых случаях я знаю что-то, что я хочу выйти из потока и уведомить как BBB, так и CCC. поскольку я нахожусь в потоке (Win32Thread), это функция void, которую я запускаю в потоке, поэтому я не могу вернуть значение в CCC.
Я новичок в C (из области c #) и не знаю, как это сделать. (уведомление) примечание: я не могу изменить эту структуру. Я могу только добавлять или вносить незначительные изменения в функции классов. это большой процесс, который выполняется в потоках и большом коде.
Есть идеи? пожалуйста, не грязный, если это возможно 🙂
добавление примера мне очень поможет.
Ответ №1:
Я не слишком понимаю вашу проблему, она слишком общая. И вы не указали, какие библиотеки многопоточности вы используете.
Для отправки сообщений между потоками обычно используются очереди сообщений с дескрипторами ожидания, блокировкой и семафорами для их синхронизации.
Конечно, вам нужна безопасная многопоточная очередь для отправки ваших сообщений между потоками.
Одно из возможных решений:
Если потоку A необходимо отправить сообщение потоку B, поместив его в очередь потока B, разбудив его, если он находится в состоянии ожидания, например, с помощью события ожидания. Поток B получает сообщение и отвечает, отправляя другое сообщение в очередь.
Другое возможное решение:
Потоку A необходимо отправить сообщение потоку B и получить ответ, блокируя поток A до тех пор, пока ответ не будет получен. Поток A помещает сообщение в очередь потока B, объект message может находиться в стеке функций. Затем он пробуждает поток B, если он находится в состоянии ожидания, а затем переходит в состояние ожидания, например, через дескриптор ожидания или семафор. Поток B, когда выводит сообщение из очереди, записывает ответ в объект, отправленный потоком A, и выводит поток A из состояния ожидания. Поле объекта должно быть помечено как изменяемое, поскольку к нему обращаются для чтения записи два потока. Затем поток A использует значение, сохраненное в объекте message, и удаляет объект из стека.
Звучит сложно, но реализация довольно проста.
Если вы используете ОС Windows, вы можете просто использовать очередь сообщений Windows, создавая невидимые окна сообщений, по одному для каждого потока. Используйте postMessage для первого случая, SendMessage для второго случая.
Ответ №2:
Если вы не боитесь решения, специфичного для Windows: вызовите PeekMessage()
из BBB
потока. Это создаст для него очередь сообщений Windows. (У основного потока уже есть один). Теперь вы можете использовать SendMessage()
для отправки сообщения из AAA
в другие потоки. Обратите внимание, что вы отправляете потоки, а не классы. Любой вызов GetMessage()
увидит ваши сообщения.
Ответ №3:
типичный дизайн, который я использую для потоков, — это потоковая функция, которой передается экземпляр класса, который ее содержит (который также содержит переменные экземпляра для этого потока). Так ли это для вас? Есть ли в потоке какой-либо экземпляр класса, переданный в него? если они это делают, то просто следите за ними извне и добавляйте свойства BOOL, которые указывают, когда нужно остановиться. В основных циклах потоков вы просто проверяете флаг, чтобы увидеть, есть ли у вас какие-либо бизнес-циклы. Это единственный чистый способ выйти из потока.