Какой дескриптор передать в CreateIoCompletionPort, если используется IOCP для базовой сигнализации? - PullRequest
0 голосов
/ 06 декабря 2018

Справочная информация : Как описано в этой статье, Разработка приложений для высокой производительности :

Рассмотрите возможность использования PostQueueCompletionStatus вместо SetEvent API.Последний увеличивает приоритет целевого потока на 1, что может привести к вытеснению чего-то еще.

Я работаю в C на Windows, и я хотел бы заменить сигнализацию в fifo производителя / потребителя с SetEvent / WaitForSingleObject на порты завершения ввода-вывода.

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

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

Короткая версия : Я хочу переключить что-то вроде этого

void Produce(int some_item)
{
    Enqueue(some_item);
    SetEvent(hndEvent);
}

void Consume(void)
{
    while (true) 
    {
        if (WaitForSingleObject(hndEvent, INFINITE) == WAIT_OBJECT_0)
        {
            // consume
        }
    }
}

на что-то вроде этого, я думаю:

void Produce(int some_item)
{
    Enqueue(some_item);

    unsigned long evt = 1; // "item enqueued"
    PostQueuedCompletionStatus(hndIOCP, 0, evt, NULL);
}

void Consume(void)
{
    while (true) 
    {
        unsigned long evt;
        LPOVERLAPPED ovlp;
        if (!GetQueuedCompletionStatus(hndIOCP, NULL, &evt, &ovlp, INFINITE))
            break;

        // consume
    }
}

Но так как я не использую этот IOCP для чего-либо, кроме сигнализации, какую ручку я должен передать CreateIoCompletionPort?

Я думал, что просто сделаю что-то вроде:

// single thread IOCP
hndIOCP = CreateIoCompletionPort(NULL, NULL, 0, 1);

но он просто возвращает NULL.

1 Ответ

0 голосов
/ 06 декабря 2018

Я нашел ответ, я пропустил следующую часть в документации для CreateIoCompletionPort.

Первый параметр - FileHandle, и если он не используется, его необходимо установитьв INVALID_HANDLE_VALUE вместо нуля.

FileHandle [in]

Дескриптор открытого файла или INVALID_HANDLE_VALUE.

  • Дескриптор должен соответствовать объекту, поддерживающему перекрывающийся ввод-вывод.

  • Если имеется дескриптор, его необходимо открыть для перекрывающегося I/ O завершение.Например, вы должны указать флаг FILE_FLAG_OVERLAPPED при использовании функции CreateFile для получения дескриптора.

  • Если INVALID_HANDLE_VALUE указано, функция создает порт завершения ввода / вывода, не связывая его с дескриптором файла.В этом случае параметр ExistingCompletionPort должен быть NULL, а параметр CompletionKey игнорируется.

...