我在 c#的线程中有点新,一般来说,
在我的程序中我使用mutex
只允许1个线程进入一个关键部分,并且由于未知原因做了一些cw打印,我可以看到超过1个线程进入我的关键部分,这是我的代码:
Mutex m = new Mutex();
m.WaitOne();
<C.S> // critical section here
m.ReleaseMutex();
我非常想知道我是否在这里犯了一个错误,感谢您的帮助。
编辑:
我的代码包含类,因此基本上看起来更像是这样:
public class test
{
private mutex m;
public test()
{
m = new mutex();
}
public func()
{
m.WaitOne();
<C.S> // critical section here
m.ReleaseMutex();
}
}
答案 0 :(得分:55)
这里的问题是所有来电者都使用不同的互斥锁;你需要锁定对象共享,通常是将它作为一个字段。例如,切换到更简单的lock
比喻:
private readonly object syncLock = new object();
public void ThreadSafeMethod() {
lock(syncLock) {
/* critical code */
}
}
或使用互斥锁:
private readonly Mutex m = new Mutex();
public void ThreadSafeMethod() {
m.WaitOne();
try {
/* critical code */
} finally {
m.ReleaseMutex();
}
}
答案 1 :(得分:5)
这种模式根本没有锁定。每个线程都会创建一个新的Mutex对象,并立即为其拥有锁。其他线程创建并使用新的Mutex本身。
考虑使用常规锁()!
lock(_lockobject) {
// do inside what needs to be done - executed on a single thread only
}
其中_lockobject是您班级中的一个简单私有变量:
private object _lockobject;
编辑:感谢评论者!情况存在,锁(这)可能是危险的。所以我删除了。
答案 2 :(得分:5)
看起来你给每个线程都有自己的互斥锁。那不行。
在大多数情况下,Mutex都是矫枉过正的。你只需要:
private static object syncLock = new object(); // just 1 instance
....
lock(syncLock)
{
// critical section
}
答案 3 :(得分:1)
Mutex用于标识运行的应用程序实例。
using (Mutex mutex = new Mutex(true, "app name", out createdNew))
{
if (createdNew)//check app is already run
{
KillOthers();
StartApp();
}
else
{
MessageBox.Show("Another instance already running!");
}
}
答案 4 :(得分:-2)
我可以对接受的答案进行更正吗?
private readonly Mutex m = new Mutex();
public void ThreadSafeMethod() {
while(!m.WaitOne()){}
try {
/* critical code */
} finally {
m.ReleaseMutex();
}
}