在c#中使用互斥锁

时间:2011-04-22 11:19:48

标签: c# multithreading mutex

我在 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();
     }


    } 

5 个答案:

答案 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();
    }
}