FCount
также защищен FQueueLock
? Если нет, то ваша проблема заключается в увеличении FCount
после того, как опубликованное сообщение уже обработано.
Вот что может происходить:
- B входит в критическую секцию
- B звонки
PostMessage
- A получает сообщение, но ничего не делает, поскольку
FCount
равно 0
- В приращений
FCount
- B оставляет критическую секцию
- А сидит там как утка
Быстрое решение - увеличить FCount
перед вызовом PostMessage
.
Имейте в виду, что все может произойти быстрее, чем можно было ожидать (т. Е. Сообщение, отправленное с PostMessage, было перехвачено и обработано другим потоком, прежде чем вы сможете увеличить FCount несколькими строками позже), особенно когда вы находитесь в истинная многопоточная среда (несколько процессоров). Вот почему я спросил ранее, имеет ли «проблемная машина» несколько процессоров / ядер.
Простой способ устранения проблем, подобных этим, состоит в том, чтобы создать код с дополнительной регистрацией для регистрации при каждом вводе метода, входа / выхода из критического раздела и т. Д. Затем вы можете проанализировать журнал, чтобы увидеть истинный порядок событий.
В отдельном примечании, небольшая оптимизация, которую можно выполнить в сценарии производитель / потребитель, как это, заключается в использовании двух очередей вместо одной. Когда потребитель просыпается, чтобы обработать полную очередь, вы меняете полную очередь на пустую и просто блокируете / обрабатываете полную очередь, в то время как новая пустая очередь может быть заполнена без двух потоков, пытающихся заблокировать очереди друг друга. Тем не менее, вам все равно понадобится блокировка в обмене двумя очередями.