Увеличение MAXIMUM_WAIT_OBJECTS для WaitforMultipleObjects - PullRequest
5 голосов
/ 28 февраля 2011

Как проще всего ждать больше объектов, чем MAXIMUM_WAIT_OBJECTS? MSDN перечисляет это:

  • Создайте поток для ожидания на дескрипторах MAXIMUM_WAIT_OBJECTS, затем ожидайте этот поток плюс другие дескрипторы. Используйте эту технику, чтобы разбить ручки на группы MAXIMUM_WAIT_OBJECTS.
  • Звоните RegisterWaitForSingleObject, чтобы ждать на каждой ручке. Поток ожидания из пула потоков ожидает MAXIMUM_WAIT_OBJECTS зарегистрированных объектов и назначает рабочий поток после сигнализации объекта или истечения интервала времени ожидания.

Но и они не очень ясны. Ситуация будет ожидать массив из более чем тысячи дескрипторов для потоков.

Ответы [ 3 ]

6 голосов
/ 28 февраля 2011

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

И название IOCP вводит в заблуждение, вы также можете легко использовать IOCP для своих собственных структур синхронизации.

3 голосов
/ 16 августа 2012

Я столкнулся с этим ограничением в WaitForMultipleObjects и пришел к выводу, что у меня есть три варианта:

  • ВАРИАНТ 1. Измените код на создайте отдельные потоки для вызова WaitForMultipleObjects в пакетном режимеменьше чем MAXIMUM_WAIT_OBJECTS.Я отказался от этой опции, потому что, если уже есть 64+ потоков, борющихся за один и тот же ресурс, я хотел бы избежать создания еще большего количества потоков, если это возможно.
  • ОПЦИЯ 2. Повторно внедрить код, используя другую технику (например, IOCP).Я тоже отказался от этого, потому что кодовая база, над которой я работаю, проверена, проверена и стабильна.Кроме того, у меня есть дела поважнее!
  • ОПЦИЯ 3. Реализовать функцию, которая разбивает объекты на пакеты, меньшие, чем MAXIMUM_WAIT_OBJECTS, и повторно вызывает WaitForMultipleObjects в одном и том же потоке .

Итак, выбраввариант 3 - вот код, который я реализовал ...

class CtntThread
{
    public: 
        static DWORD WaitForMultipleObjects( DWORD, const HANDLE*, DWORD millisecs );
};

DWORD CtntThread::WaitForMultipleObjects( DWORD count, const HANDLE *pHandles, DWORD millisecs )
{
    DWORD retval = WAIT_TIMEOUT;

    // Check if objects need to be split up. In theory, the maximum is
    // MAXIMUM_WAIT_OBJECTS, but I found this code performs slightly faster
    // if the object are broken down in batches smaller than this.
    if ( count > 25 )
    {
        // loop continuously if infinite timeout specified
        do
        {
            // divide the batch of handles in two halves ...
            DWORD split = count / 2;
            DWORD wait = ( millisecs == INFINITE ? 2000 : millisecs ) / 2;
            int random = rand( );

            // ... and recurse down both branches in pseudo random order
            for ( short branch = 0; branch < 2 && retval == WAIT_TIMEOUT; branch++ )
            {
                if ( random%2 == branch ) 
                {
                    // recurse the lower half
                    retval = CtntThread::WaitForMultipleObjects( split, pHandles, wait );
                }
                else
                {
                    // recurse the upper half
                    retval = CtntThread::WaitForMultipleObjects( count-split, pHandles+split, wait );
                    if ( retval >= WAIT_OBJECT_0 && retval < WAIT_OBJECT_0+split ) retval += split;
                }
            }
        }
        while ( millisecs == INFINITE && retval == WAIT_TIMEOUT );
    }
    else
    {
        // call the native win32 interface
        retval = ::WaitForMultipleObjects( count, pHandles, FALSE, millisecs );
    }

    // done
    return ( retval );
}
2 голосов
/ 28 февраля 2011

Посмотрите здесь .

Если вам нужно подождать более чем дескрипторы MAXIMUM_WAIT_OBJECTS, вы можете создать отдельный поток для ожидания MAXIMUM_WAIT_OBJECTS, а затем подождатьна этих нитях до конца.Используя этот метод, вы можете создавать потоки MAXIMUM_WAIT_OBJECTS, каждый из которых может ожидать дескрипторы объекта MAXIMUM_WAIT_OBJECTS.

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