проверка двух очередей без привязки процессора - PullRequest
1 голос
/ 03 июля 2011

У меня есть система пула потоков, которая использует передачу сообщений для организации событий, и я также использую Windows API, который также выполняет небольшую передачу сообщений. Поэтому по сути мне нужно использовать функции, которые проверяют наличие сообщений без блокировки. Если я блокирую (если я использую GetMessage, я думаю, что он заблокирует) во время проверки любой очереди, я могу пропустить любые входящие сообщения в другой очереди.

Первое решение, которое я знаю, это Sleep пару миллисекунд где-то во время цикла просмотра двух очередей.

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

Есть ли другие хорошие решения?

Ответы [ 3 ]

1 голос
/ 03 июля 2011

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

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

Если вам нужна дополнительная помощь, не могли бы вы более четко описать потоксообщений Windows и / или рабочих объектов через вашу систему?Неясно, откуда берется работа для пула потоков и как она транспортируется (если я вынужден использовать WMQ, я обычно публикую сообщение в wParam / lParam, но в вашей системе?).

RgdsМартин

0 голосов
/ 04 июля 2011

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

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

CreateIoCompletionPort с дескриптором null создаст порт завершения и вернет дескриптор. Передача нуля, когда NumberOfConcurrentThreads указывает операционной системе поддерживать столько потоков, сколько доступно ядер.

Создайте любое количество рабочих потоков (на несколько больше, чем у вас ядер) и CreateIoCompletionPort с дескриптором, возвращаемым при первом вызове. Это свяжет рабочих с этим портом завершения. Теперь позвоните GetQueuedCompletionStatus с INFINITE тайм-аутом на каждого работника, который заблокирует их на неопределенный срок.

Создайте struct, у которого в качестве первого члена есть ПЕРЕКРЫТИЕ, плюс любые данные, которые вы хотите передать как задачу (некоторые указатели на данные или что-то еще).

Для каждой задачи настройте одну из своих структур сообщений и PostQueuedCompletionStatus для дескриптора порта завершения. При выходе из приложения, отправьте ноль. Вы можете использовать поле dwNumberOfBytesTransferred (и ключ завершения) для передачи дополнительной информации.

Теперь Windows будет пробуждать одну ветку для каждого отправленного вами сообщения, в порядке очередности до количества доступных ядер. Если один из рабочих блоков в IO блокируется, Windows пробуждает другого для другой задачи (если процессор занят, пока есть работа).

После завершения задания вернитесь к GetQueuedCompletionStatus.

Чтобы изящно завершить работу всех работников, нужно передать «ноль переданных байтов» и заставить работника повторно опубликовать событие и выйти, если он с этим столкнется.

0 голосов
/ 03 июля 2011

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

...