Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# c语言中互斥体的使用#_C#_Multithreading_Mutex - Fatal编程技术网

C# c语言中互斥体的使用#

C# c语言中互斥体的使用#,c#,multithreading,mutex,C#,Multithreading,Mutex,我在c#和一般情况下对线程有点陌生, 在我的程序中,我使用mutex只允许1个线程进入临界区,由于未知原因,通过执行一些cw打印,我可以看到超过1个线程进入临界区,这是我的代码: Mutex m = new Mutex(); m.WaitOne(); <C.S> // critical section here m.ReleaseMutex(); Mutex m=new Mutex(); m、 WaitOne(); //这里是临界截面 m、 释放互斥锁(); 我很想知道我是否犯了

我在c#和一般情况下对线程有点陌生, 在我的程序中,我使用
mutex
只允许1个线程进入临界区,由于未知原因,通过执行一些cw打印,我可以看到超过1个线程进入临界区,这是我的代码:

Mutex m = new Mutex();
m.WaitOne();
<C.S> // critical section here
m.ReleaseMutex();
Mutex m=new Mutex();
m、 WaitOne();
//这里是临界截面
m、 释放互斥锁();
我很想知道我是否犯了错误,提前谢谢你的帮助

编辑:

我的代码包含类,因此基本上看起来更像这样:

public class test
{
    private mutex m;
    public test()
    {
         m = new mutex();
    }
    public func()
    {
         m.WaitOne();
         <C.S> // critical section here
         m.ReleaseMutex();
     }


    } 
公共类测试
{
专用互斥锁m;
公开考试()
{
m=新的互斥体();
}
公共职能
{
m、 WaitOne();
//这里是临界截面
m、 释放互斥锁();
}
} 

这里的问题是,您的所有呼叫者都在使用不同的互斥锁;您需要共享锁定对象,通常是将其设为字段。例如,切换到更简单的
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();
    }
}

此模式根本不锁定。每个线程创建一个新的互斥对象,并立即拥有该对象的锁。其他线程自己创建并使用新的互斥锁

考虑使用常规锁()

其中_lockobject是类中的一个简单私有变量:

private object _lockobject; 

编辑:感谢评论!存在锁(此)可能有危险的情况。所以我把它去掉了

看起来每个线程都有自己的互斥锁。那不行

而互斥在大多数情况下都是杀伤力过大的。您只需要:

private static object syncLock = new object();  // just 1 instance

....

lock(syncLock)
{
    // critical section
}

互斥用于标识运行应用程序实例

 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!");
                }
            }

我可以对接受的答案加上一个更正吗

private readonly Mutex m = new Mutex();
public void ThreadSafeMethod() {
    while(!m.WaitOne()){}
    try {
        /* critical code */
    } finally {
        m.ReleaseMutex();
    }
}

我使用的互斥体是一个类的全局互斥体,所以我认为它是相同的mutex@Nadav-这不是你的问题所显示的。。。您的问题将其显示为与代码相同的位置,即局部变量.Nadav-您确定该类没有多个实例吗?几乎所有的“锁/互斥对象允许多个调用通过”问题都是锁/互斥对象比您预期的多。不要
lock(this)
,或
lock(someType)
,或
lock(anyString)
-这些都是糟糕的设计,并不健壮。顺便说一句,锁定这并不是一个好主意,更好的做法是创建简单的对象锁类型变量(这不被认为是好的做法)。(例如,见)。制作一个只用于锁定的对象要好得多,而且忘记曾经出现过允许锁定任何对象的.NET设计错误。@WillDean-的确;我宁愿有一个特定的类型,例如
Monitor
实例。而且,
对象
应该是
抽象的
;我不确定从这个问题,我们可以推断出
静态
是有意的。。。虽然我们不能推断它也不是;p@Marc对的我使用static作为错误的反面。代码不完全清楚。必须有一个以上的类实例。这是一个实例级互斥;您确定您的编码不在单独的不相关实例的关键部分吗?此外,任何错误都将使代码永久锁定-您需要进行
尝试
/
最终
才能确保安全。编辑后:此互斥锁仅在对象级别工作,即1个CrticialSection/实例。这就是你想要的吗?信息:
Mutex
Is
mutual exclusion
Hi-Emanuele。为什么你认为你的答案是进步?循环:
while(!m.WaitOne()){}
永远不会运行多次,因为没有参数的方法总是返回
true
(除非它永远不会返回)。
private readonly Mutex m = new Mutex();
public void ThreadSafeMethod() {
    while(!m.WaitOne()){}
    try {
        /* critical code */
    } finally {
        m.ReleaseMutex();
    }
}