Как создать механизм ожидания один-ко-многим в WinAPI - PullRequest
3 голосов
/ 12 августа 2011

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

Как создать механизм синхронизации для удовлетворения этих требований:

  1. Поток Writer записывает все данные в буфер и позволяет всем потокам чтения работать одновременно (хорошо, я сделал это с семафором).Затем ждет всех из них , чтобы завершить свой ход.Я не мог использовать WaitForMultipleObjects, поскольку потоки не заканчиваются, а заканчивается один цикл цикла.Может быть, событие для каждого потока считывателя, и когда цикл завершится, они будут сигнализировать об этом, а Writer будет использовать WaitForMultipleObjects, чтобы дождаться завершения всех циклов цикла?
  2. Потоки считывателя читают свои данные, выполняют свою работу для этого циклаи как-нибудь позволить Writer потоку поставить следующие данные.Обратите внимание, что Writer должен начать свой следующий цикл цикла, когда все потоки завершат свой ход.

Как реализовать такой механизм?Как я уже сказал, единственное, о чем я могу думать, кажется:

Автор:

for (;;) 
{
    PutDataIntoBuffer();
    for (i = 0; i < threadCount; ++i)
    {
        ResetEvent(threadEvents[i]); //so that all events will be nonsignaled
    }
    ReleaseSemaphore(sem, threadCount, NULL);
    WaitForMultipleObjects(threadCount, threadEvents, TRUE, INFINITE);
}

Читатели:

for (;;)
{
    WaitForSingleObject(sem, INFINITE);
    DoWhateverToBeDoneWithData();
    SetEvent(threadEvents[myThreadIndex]); //writer, wait for me too!
}

Каковы лучшие способы сделать это?

Ответы [ 2 ]

3 голосов
/ 12 августа 2011

Вы должны использовать Readers-writer lock .

В Windows есть Slim Reader / Writer блокировка , которую я рекомендую вам посмотреть.

1 голос
/ 13 августа 2011

Если вы используете VC10, вам лучше использовать Concurrency :: unbounded_buffer класс, который будет обрабатывать все для вас. Просто используйте Concurrency::send, Concurrency::asend, чтобы добавить к нему сообщение; Concurrency::receive, Concurrency::try_receive чтобы прочитать сообщение с него. Этот класс реализует FIFO. Может быть несколько читателей, а также несколько авторов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...