我有2个线程同时被触发并且并行运行。这2个线程将操纵字符串值,但我想确保没有数据不一致。为此,我想使用Monitor.Pulse
和Monitor.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个并行线程进行通信(操作相同的资源)?
答案 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。