6

WinNT v6.x 以降でスレッドを同期するために、新しい条件変数プリミティブまたは Windows イベントのいずれかを使用できます。次の 2 つのアプローチを検討してください。main で「go」が設定されている場合はワーカーを同時に実行する必要があります。それ以外の場合は、すべてブロックする必要があります。

/*language C code*/
/*Windows Condition Variable*/
int go=0;
CONDITION_VARIABLE cv;
SRWLOCK lock;
void workers()
{
    AcquireSRWLockShared(&lock);
    if(go==0)
    {
        SleepConditionVariableSRW(&cv, &lock, INFINITE, CONDITION_VARIABLE_LOCKMODE_SHARED);
    }
    ReleaseSRWLockShared(&lock);
    /*
    Workers continue...
    */
}
void main()
{
    int i;
    InitializeConditionVariable(&cv);
    InitializeSRWLock(&lock);
    for(i=0;i<10;i++)
    {
        CreateThread(0, 0, workers, 0, 0, 0);
    }
    AcquireSRWLockExclusive(&lock);
    go=1;
    ReleaseSRWLockExclusive(&lock);
    WakeAllConditionVariable(&cv);
}

また

/*language C code*/
/*Windows Event*/
HANDLE go;
void workers()
{
    WaitForSingleObject(go, INFINITE);
    /*
    Workers continue...
    */
}
void main()
{
    int i;
    go=CreateEvent(0,1,0,0); /*No security descriptor, Manual Reset, initially 0, no name*/
    for(i=0;i<10;i++)
    {
        CreateThread(0, 0, workers, 0, 0, 0);
    }
    SetEvent(go);
}

最初のアプローチでは、ワーカーは SleepConditionVariableSRW でブロックされ、WakeAllConditionVariableで起動されます2 つ目では、 WaitForSingleObjectでブロックされ、 SetEventによって起動されます。

オーバーヘッドに関してのみ、実際にはどちらが優れていますか? (ヒント:コンテキスト スイッチロック競合ブロッキング スレッドのオーバーヘッド)

私は最初を選びますが、正当化の欠如を感じます。

4

2 に答える 2

5

この特定のユースケースは、イベントに最適です。これは、待機中のすべてのスレッドをウェイクアップする必要があるワンショットプロセスです。

条件変数は、待機中のスレッドがウェイクアップしたときにtrueであるかどうかに関係なく、関連する述語があるキューなどに適しています(キュー上のアイテムなど、別のスレッドによって消費された可能性があります)。ウェイクアップされたスレッドは、後で発生するスレッドではなく、条件変数が通知されたときにすでに待機しているスレッドの1つであることが重要です。

さらに、ハンスが指摘したように、Windowsのネイティブ条件変数はVista以降でのみ機能するため、WindowsXPとの互換性が懸念される場合は使用できません。

于 2011-03-08T15:57:59.183 に答える
2

条件変数のサポートには、Vista 以降が必要です。残念ながら、XP のサポートは依然として重要な傾向にあります。2 番目のスニペットには、理解するのが簡単であるという大きな利点もあります。最初のもので何をしようとしているのかわかりません。間違っているようです。

于 2011-03-08T14:23:25.530 に答える