0

私のコードの背後にある考え方は、このリストをループしたいので、一度に4つのループだけを処理したいということです。以前に書いたコードをコピーして貼り付けることができます。おっと、リソース(wc)が必要ですが、共有できません。だから私はそれらのうちの4つをスレッドごとに1つ持っています!

思った通りに行かなかった。トライロックがないので、ドキュメントにあるようにブロックしないWaitOne(0)を使用しました。ただし、インデックス==-1を示す例外を取得することはできますが、これはimoで発生するはずがありません。

なぜそれが起こっているのですか

var s = new Semaphore(0, 4);
s.Release(4);

var wcs = new MyObject();
var mutexs= new Mutex[4];
for (int i = 0; i < wcs.Count(); ++i)
{
    wcs[i] = new MyObject();
    mutexs[i] = new Mutex();
}

int counter = 0;
Parallel.ForEach(ls, v =>
{
    s.WaitOne();
    int index = -1;
    try
    {
        ++counter;
        Console.WriteLine("Counter = " + counter.ToString());
        MyObject wc = null;
        for (int i = 0; i < mutexs.Count(); ++i)
        {
            if(mutexs[i].WaitOne(0))
            {
                index = i;
                wc = wcs[i];
            }
        }
        if (index == -1)
            throw new Exception("this triggers");
        //...
    }
    finally
    {
        --counter;
        mutexs[index].ReleaseMutex();
        s.Release();
    }
});
4

1 に答える 1

3

最初のスレッドがすべての Mutex を占有しています。「break;」が必要です。「if(mutexs[i].WaitOne(0))」ステートメント内

var s = new Semaphore(0, 4);
s.Release(4);

var wcs = new MyObject();
var mutexs= new Mutex[4];
for (int i = 0; i < wcs.Count(); ++i)
{
    wcs[i] = new MyObject();
    mutexs[i] = new Mutex();
}

int counter = 0;
Parallel.ForEach(ls, v =>
{
    s.WaitOne();
    int index = -1;
    try
    {
        ++counter;
        Console.WriteLine("Counter = " + counter.ToString());
        MyObject wc = null;
        for (int i = 0; i < mutexs.Count(); ++i)
        {
            if(mutexs[i].WaitOne(0))
            {
                index = i;
                wc = wcs[i];
                break; //Use only one Mutex per thread
            }
        }
        if (index == -1)
            throw new Exception("this triggers");
        //...
    }
    finally
    {
        --counter;
        mutexs[index].ReleaseMutex();
        s.Release();
    }
});
于 2013-03-01T03:20:27.360 に答える