7

次のコードは、10 スレッドすべてを一度に 2 つずつ実行し、Release()10 回呼び出された後に「完了」を出力すると考えました。しかし、それは起こったことではありません:

        int count = 0;

        Semaphore s = new Semaphore(2, 2);
        for (int x = 0; x < 10; x++)
        {
            Thread t = new Thread(new ThreadStart(delegate()
            {
                s.WaitOne();
                Thread.Sleep(1000);
                Interlocked.Increment(ref count);                       
                s.Release();
            }));
            t.Start(x);
        }

        WaitHandle.WaitAll(new WaitHandle[] { s });
        Console.WriteLine("done: {0}", count);

出力:

done: 6

私が探している機能を実装する唯一の方法が、EventWaitHandle各スレッドにan を渡し、WaitAll()それらの配列に対してa を実行することである場合、セマフォのみの配列に対してEventWaitHandlesa を実行する意味は何ですか? WaitAll()つまり、待機中のスレッドのブロックが解除されるのはいつですか?

4

2 に答える 2

5

WaitHandle.WaitAllすべてのハンドラーがシグナル状態になるまで待機します。

したがって、1つWaitHandle.WaitAllを呼び出すと、呼び出したのと同じように機能します WaitHandles.WaitOne()

たとえば、次のコードを使用して、開始されたすべてのスレッドを待機しながら、2 つのスレッドを並行して実行できるようにすることができます。

int count = 0;

Semaphore s = new Semaphore(2, 2);
AutoResetEvent[] waitHandles = new AutoResetEvent[10];
for (int x = 0; x < 10; x++)
    waitHandles[x] = new AutoResetEvent(false);

for (int x = 0; x < 10; x++)
{
    Thread t = new Thread(threadNumber =>
        {
            s.WaitOne();
            Thread.Sleep(1000);
            Interlocked.Increment(ref count);
            waitHandles[(int)threadNumber].Set();
            s.Release();
        });
    t.Start(x);
}

WaitHandle.WaitAll(waitHandles);
Console.WriteLine("done: {0}", count);
于 2013-01-25T20:38:48.003 に答える
1

WaitHandle.WaitAll(new WaitHandle[] { s });のように待ちますs.WaitOne();。いち早く入ります。この呼び出しが他のすべてのセマフォ操作を待機することを期待しているようですが、オペレーティング システムが違いを判断できる方法はありません。このコマンドは、セマフォへのアクセスを許可された最初のコマンドである可能性があります。

Barrier必要なのはクラスだと思います。fork-join スタイルの並列処理用に作成されています。

于 2013-01-25T20:38:28.187 に答える