Какую схему синхронизации выбрать, чтобы избежать тупика в приложении C ++ / MFC в реальном времени? - PullRequest
2 голосов
/ 05 октября 2011

Я хотел бы задать вам вопрос относительно того, какое средство параллелизма (CMutex, CSemaphore, CEvent) я должен выбрать, чтобы сделать приложение C ++ / MFC многопоточным.

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

Одна итерация моего рабочего процесса следующая. У меня есть 2 производителя A, B (MFC Workers), которым нужно заполнить две отдельные структуры данных (по 1 каждый). Третий поток, потребитель (в том числе и MFC Worker), блокируется до тех пор, пока обе данные не станут доступны из A и B. Затем производители A и B должны заблокировать (каждый после завершения своих данных), C должен проснуться, выполнить расчет, разблокировать A и B, чтобы продолжить и снова заблокировать, ожидая следующих сегментов.

  1. Я не должен использовать очереди (как у актера) - требуется блокировка (
  2. Я попробовал CEvent, и он работает. AutoResetEvents для A, B, чтобы разблокировать Вызов CMultiLock на C, а затем ManualResetEvent-> Set () из C, чтобы разблокировать A и B в ожидании последнего события. Меня беспокоит, когда сбросить это событие (например, если пропустить весь сет, а затем сбросить).
  3. Могут ли семафоры с множеством 2 обозначать лучшее решение?

С уважением.

Ответы [ 4 ]

2 голосов
/ 05 октября 2011

C должен ждать, пока произойдут две вещи, поэтому наиболее логичным является то, что он ожидает двух CEvent объектов с автосбросом: один устанавливается A, а другой - B.

Когда C завершен, A и B должны затем ждать уведомления.Поскольку существует два потока, и оба должны проснуться, естественным является использование другой пары объектов CEvent с автосбросом, по одному для каждого из A и B. После этого C может установить оба этих параметра.

Семафор со счетчиком 2 будет работать для пробуждения C --- C ждет дважды, и каждый из A и B уведомляет --- но это означает, что C должен проснуться после первого уведомления, чтобы ждатьво-вторых, это не идеально.

Использование семафора со счетом 2 для последующего пробуждения A и B может привести к краже пробуждений и путанице.С сигнализирует семафор дважды.Просыпается и принимает сигнал, выполняет его обработку и уведомляет C, а затем снова ожидает семафор.Поскольку B еще не проснулся, семафор все еще доступен, поэтому A снова его берет.В то же время B не застрял, так как он не получит другого сигнала, а C застрял, поскольку он будет ожидать следующего значения от B.

Альтернативой является использование API Windows Condition Variable вместо событий, но, похоже, для этого нет оболочки MFC.Смотри http://msdn.microsoft.com/en-us/library/ms682052%28VS.85%29.aspx

2 голосов
/ 05 октября 2011

Я бы пошел на небольшую модификацию вашего варианта 2 - использовать CMultiLock для двух событий, чтобы заблокировать C; затем используйте другую пару событий, чтобы заблокировать A и B. C установит два события автоматического сброса, чтобы разбудить каждого из A и B. Тогда у вас больше не будет гонки за сброс.

0 голосов
/ 06 октября 2011

Вы можете просто использовать объекты CEvent, а не WaitForMultipleObjects (), что позволяет вам ждать обоих объектов с помощью третьего параметра 'bWaitAll'.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025%28v=vs.85%29.aspx

0 голосов
/ 05 октября 2011

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

A starts
A writes A-Data
A signals
A stops

B starts
B writes B-Data
B signals 
B stops

C starts
C reads A-Data and B-Data
C starts A, B
C stops


*Signal Class*

Mutex protected counter attribute

Receives signal for A, increment counter
Receives signal for B, increment counter
IF counter equals 2,  clear counter and start C
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...