并行线程的资源访问

时间:2013-11-19 06:24:24

标签: c# multithreading locking

我有2个线程同时被触发并且并行运行。这2个线程将操纵字符串值,但我想确保没有数据不一致。为此,我想使用Monitor.PulseMonitor.Wait锁定。我在另一个问题/答案中使用了一种方法,但每当我运行程序时,第一个线程就会卡在Monitor.Wait级别。我认为这是因为第二个线程已经“脉冲”和“等待”。以下是一些要查看的代码:

string currentInstruction;

public void nextInstruction() 
{
    Action actions = {
        fetch,
        decode
    }
    Parallel.Invoke(actions);
    _pc++;
}

public void fetch()
{
    lock(irLock) 
    {
        currentInstruction = "blah";
        GiveTurnTo(2);
        WaitTurn(1);
    }

    decodeEvent.WaitOne();
}

public void decode()
{
    decodeEvent.Set();

    lock(irLock) 
    {
        WaitTurn(2);
        currentInstruction = "decoding..."
        GiveTurnTo(1);
    }
}

// Below are the methods I talked about before.

// Wait for turn to use lock object
public static void WaitTurn(int threadNum, object _lock)
{
    // While( not this threads turn )
    while (threadInControl != threadNum)
    {
        // "Let go" of lock on SyncRoot and wait utill 
        // someone finishes their turn with it
        Monitor.Wait(_lock);
    }
}

// Pass turn over to other thread
public static void GiveTurnTo(int nextThreadNum, object _lock)
{
    threadInControl = nextThreadNum;
    // Notify waiting threads that it's someone else's turn
    Monitor.Pulse(_lock);
}

任何想法如何使用锁或其他任何东西在同一周期内获得2个并行线程进行通信(操作相同的资源)?

1 个答案:

答案 0 :(得分:0)

你想并行运行2个和平的代码,但是在开始时使用相同的变量锁定它们吗?

正如nvoigt所说,这听起来已经错了。你要做的就是从那里删除lock。仅在您即将访问某些内容时使用它。

可以通过不必拥有它们来避免“数据不一致”。不要直接使用currentInstruction字段(是字段吗?),而是提供线程安全的CurrentInstruction属性。

private object _currentInstructionLock = new object();
private string _currentInstruction
public string CurrentInstruction
{
    get { return _currentInstruction; }
    set
    {
        lock(_currentInstructionLock)
            _currentInstruction = value;
    }
}

其他的是命名,从_开始的局部变量名称是一种不好的风格。有些人(包括我)使用它们来区分私人领域。属性名称应从BigLetter和本地变量fromSmall。

开始