0

winapi 条件変数がどのように機能するかを理解するのに問題があります。

より具体的に言えば、私が欲しいのは、いくつかのスレッドが何らかの条件で待機していることです。次に、WakeAllConditionVariable() 呼び出しを使用してすべてのスレッドを起動し、それらが機能できるようにします。スレッドを開始したいだけであるという事実に加えて、それらが動作を開始するための他の前提条件はありません(nプロデューサー/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;
}

このコードは、私が期待することをしません。1 つのスレッドだけがジョブを終了することもあれば、2 つまたは 3 つのスレッドが終了することもありますが、すべてのスレッドが終了することはありません。main 関数が WaitForMultipleObjects() 呼び出しを通過することはありません。

何が間違っていたのか正確にはわかりませんが、どこかで同期の問題があると思いますか?

どんな助けでも大歓迎です。(古いトピックを別のドレッシングで再投稿した場合は申し訳ありません:)

4

1 に答える 1

4

cond_rwlock および start_condition 変数の初期化が遅すぎます。スレッドを開始する前に、コードを上に移動します。特にマルチコア マシンでは、スレッドがすぐに実行を開始する可能性があります。

API 関数の戻り値をテストします。失敗をチェックしないため、なぜ機能しないのかわかりません。

于 2010-10-29T17:23:47.867 に答える