Проблема пробуждения нескольких потоков с помощью условной переменной API в win32 - PullRequest
0 голосов
/ 29 октября 2010

У меня проблема с пониманием того, как работают переменные условия winapi.

Что касается более конкретной стороны, то мне нужна пара потоков, ожидающих какого-либо условия. Затем я хочу использовать вызов WakeAllConditionVariable (), чтобы разбудить все потоки, чтобы они могли работать. Помимо того, что я просто хочу, чтобы потоки были запущены, нет никаких других предпосылок для того, чтобы они начали работать (как это было бы в сценарии с n продюсерами / потребителями).

Вот код на данный момент:

#define MAX_THREADS 4

CONDITION_VARIABLE  start_condition;
SRWLOCK            cond_rwlock;
bool                  wake_all;

__int64 start_times[MAX_THREADS];

Основная нить:

int main() 
{
    HANDLE h_threads[ MAX_THREADS ];

    int tc;
    for (tc = 0; tc < MAX_THREADS; tc++)
    {
        DWORD tid;
        h_threads[tc] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_routine,(void*)tc,0,&tid);
        if( h_threads[tc] == NULL )
        {
            cout << "Error while creating thread with index " << tc << endl;
            continue;
        }
    }

    InitializeSRWLock( &cond_rwlock );
    InitializeConditionVariable( &start_condition );

    AcquireSRWLockExclusive( &cond_rwlock );
        // set the flag to true, then wake all threads
    wake_all = true;
    WakeAllConditionVariable( &start_condition );

    ReleaseSRWLockExclusive( &cond_rwlock );

    WaitForMultipleObjects( tc, h_threads, TRUE, INFINITE );

    return 0;
}

А вот код для подпрограммы потока:

DWORD thread_routine( PVOID p_param )
{
    int t_index = (int)(p_param);

    AcquireSRWLockShared( &cond_rwlock );

        // main thread sets wake_all to true and calls WakeAllConditionVariable()
        // so this thread should start doing the work (?)
    while ( !wake_all )
        SleepConditionVariableSRW( &start_condition,&cond_rwlock, INFINITE,CONDITION_VARIABLE_LOCKMODE_SHARED );

    QueryPerformanceCounter((LARGE_INTEGER*)&start_times[t_index]);
        // do the actual thread related work here

    return 0;
}

Этот код не делает того, чего я ожидал. Иногда только один поток завершает работу, иногда два или три, но никогда не все из них. Основная функция никогда не проходит после вызова WaitForMultipleObjects ().

Я не совсем уверен, что я сделал не так, но я бы где-нибудь предположил проблему с синхронизацией?

Любая помощь будет принята с благодарностью. (извините, если я повторно опубликовал более старую тему с другим украшением :)

1 Ответ

4 голосов
/ 29 октября 2010

Вы слишком поздно инициализируете переменные cond_rwlock и start_condition.Переместите код вверх, , прежде чем запустите потоки.Поток, вероятно, начнет работать сразу же, особенно на многоядерном компьютере.

И протестируйте возвращаемые значения функций API.Вы не знаете, почему это не работает, потому что вы никогда не проверяете ошибки.

...