Использование событий для синхронизации потоков - PullRequest
0 голосов
/ 06 марта 2012

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

Поэтому я просто хочу спросить, выглядит ли этот способ использования событий для синхронизации потоковхорошо для вас?

Идея в том, что у нас есть функция GetSymbol, которая может быть вызвана только из основного потока.Поток сервера должен запросить у основного потока результаты этой функции.

#include <windows.h>
#include <process.h>
#include <stdio.h>

HANDLE symbol_need, symbol_ready, end;

int symbol_container;

int GetSymbol()
{
    // Only main thread can use this function.
    static int i = 0;
    return ++i;
}

void Server(void* p)
{
    printf("Ask for first symbol.\n");
    SetEvent(symbol_need);

    DWORD wait_result;

    wait_result = WaitForSingleObject(symbol_ready, INFINITE);
    if(WAIT_OBJECT_0 == wait_result)
    {
        ResetEvent(symbol_ready);
        printf("First symbol: %i\n", symbol_container);
    } else {
        printf("Something went wrong.\n");
    }

    printf("Ask for second symbol.\n");
    SetEvent(symbol_need);

    wait_result = WaitForSingleObject(symbol_ready, INFINITE);
    if(WAIT_OBJECT_0 == wait_result)
    {
        ResetEvent(symbol_ready);
        printf("Second symbol: %i\n", symbol_container);
    } else {
        printf("Something went wrong.\n");
    }

    printf("OK, finish it.");
    SetEvent(end);
}


int main(int argc, char* argv[])
{
    symbol_need = CreateEvent( NULL, FALSE, FALSE, NULL );
    symbol_ready = CreateEvent( NULL, FALSE, FALSE, NULL );
    end = CreateEvent( NULL, FALSE, FALSE, NULL );

    _beginthread(Server, 0, NULL);

    DWORD wait_result;

    while(1)
    {
        wait_result = WaitForSingleObject(symbol_need, 100);
        if(WAIT_OBJECT_0 == wait_result)
        {
            ResetEvent(symbol_need);
            symbol_container = GetSymbol();
            SetEvent(symbol_ready);
        }
        wait_result = WaitForSingleObject(end, 100);
        if(WAIT_OBJECT_0 == wait_result)
        {
            break;
        }
    }
    return 0;
} 

1 Ответ

1 голос
/ 06 марта 2012

Да, этот код правильный.

Этот пример полезен для просмотра работы событий. Однако нет необходимости заново изобретать колесо, когда вы пишете производственный код. Например, описанное вами взаимодействие может быть элегантно смоделировано с использованием параллельных структур данных, подобных тем, которые есть в библиотеке Intel TBB, например, concurrent_bounded_queue .

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