0

我的代码背后的想法是我想遍历这个列表,我只想一次处理 4 个循环。没问题,我可以复制/粘贴我之前写的代码。糟糕,我需要一个资源 (wc),但无法共享。所以我有4个,每个线程一个!

它没有像我预期的那样进行。没有 trylock 所以我使用了 WaitOne(0) ,它不应该像文档所说的那样阻塞。但是我能够得到我的异常,它显示了 index==-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

您的第一个线程占用了所有互斥锁,您需要“休息”;在你的“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 回答