Многопоточность: Signal vs BusyWait (Polling), вопросы переменных условий между потоками - PullRequest
2 голосов
/ 04 июня 2009

У меня общий вопрос о межпоточном взаимодействии.

Сейчас я использую кучу потоков C ++ (~ 15).

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

Итак, я смотрю на переменную условия и сигнал. Я думаю, что понимаю общую концепцию включения потока в .Wait (), ожидания другого потока, вызывающего .Signal ().

Вопрос № 1) Моя проблема может быть концептуальной, но если поток, ожидающий сигнала, получает SUSPENDED во время ожидания, он не может выполнить какое-либо действие самостоятельно. Можно ли как-нибудь дать ему проснуться для выполнения каких-либо действий?

Вопрос № 2) Кроме того, мой класс используется для передачи данных в обоих направлениях. Но если средний класс ожидает сигнала от другого класса, он не может отправить сигнал этому классу. Такие как:

 _________                       _________                       __________
| Class A |---newData Signal--->| Class B |---newData Signal--->| Class C  |
|         |                     |(WAITING)|<---newData Signal---|          |
 ---------                       ---------                       ----------

Таким образом, если класс B включен .Wait () для .Signal () из C, он не может обработать новый сигнал от A.

Возможно ли, чтобы оба A && C посылали один и тот же сигнал "newData" B, чтобы разбудить его? Можно ли отличить сигнал от A && C.

Я кодирую это, используя C ++, используя инфраструктуру ACE, и могу переключиться на Boost. Но я думаю, что это достаточно универсально, чтобы я мог применить ответ к любой ОС (надеюсь).

Спасибо

Ответы [ 5 ]

2 голосов
/ 04 июня 2009

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

1 голос
/ 04 июня 2009

Вопрос № 1) В большинстве реализаций вы можете ограничить максимальное время ожидания и так сказать: подождите 2 секунды, затем что-то сделать и снова ждать.

Вопрос № 2) В большинстве реализаций вы можете ожидать более одного сигнала одновременно. Вы можете сказать: проснуться, если сработал сигнал A или B.

0 голосов
/ 04 июня 2009

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

Для каждого потока измените / переопределите реализацию режима ожидания, чтобы при ожидании потока он добавлялся в конец очереди выполнения.

Предполагается, что одновременно должен работать только один поток. Последнее, что должен сделать текущий запущенный поток, прежде чем сам перейдет в режим ожидания / ожидания, - это разбудить поток в начале списка.

Если вам нужно более сложное выполнение / планирование потоков, следующим шагом является создание потока планировщика, который обходит очередь, корректируя порядок потоков в очереди, проверяя, какой поток имеет все ресурсы, которые ему необходимы беги и т. д.

0 голосов
/ 04 июня 2009

Хотя для этого можно использовать условные переменные, в описании проблемы предлагается использовать очередь сообщений. Затем поток A и поток C могут вставлять сообщения в очередь B, и B обрабатывает их соответствующим образом. (Конечно, чтобы различать два потока, вы должны организовать для A и C отправку разных сообщений.)

Я не знаю, какую поддержку для очередей сообщений имеет ACE, однако, в (скажем) среде параллелизма Java, вы можете создать собственную очередь сообщений бедняков, используя ConcurrentLinkedQueue. : -)

0 голосов
/ 04 июня 2009

Ответы, которые вы ищете, очень сложны, и места в этой вики не так много, чтобы ответить на них все: (

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

Для того, чтобы ваши коммуникации работали, вам нужно отправлять сигналы в нужные места и ждать правильных событий.

Самый простой способ сделать это, который даст вам что-то, что работает лучше, чем опрос, - это использовать одну переменную условия, которую разделяют все ваши потоки. Когда об этом состоянии сообщают, они все проснутся и будут искать какую-то работу.

Это неэффективно, но просто и будет работать для вас и более эффективно, чем опрос. Если у вас есть эта работа, вы можете попытаться ввести некоторые новые условные переменные и разделить, какие потоки ждут, на какие из них - при этом вы будете совершать много ошибок и испытывать много тупиков и голодовок. Продолжайте, и вы начнете понимать, как все это работает.

Удачи.

...