C# 中互斥体的使用

发布于 2024-11-03 03:59:26 字数 613 浏览 1 评论 0原文

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


    } 

I am a bit new in threading in c# and on general,
in my program I am using mutex to allow only 1 thread getting inside a critical section and for unknown reason with doing some cw prints I can see that more than 1 thread is getting inside my critical section and this is my code :

Mutex m = new Mutex();
m.WaitOne();
<C.S> // critical section here
m.ReleaseMutex();

I would very much like to know if I am doing a mistake here thanks in advance for your kind help.

EDIT:

My code include classes so it basically looks more like this:

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


    } 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

仙女 2024-11-10 03:59:26

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

The problem here is that all your callers are using a different mutex; you need the locking object to be shared, usually by making it a field. For example, and switching to a simpler lock metaphor:

private readonly object syncLock = new object();
public void ThreadSafeMethod() {
    lock(syncLock) {
        /* critical code */
    }
}

or using the mutex:

private readonly Mutex m = new Mutex();
public void ThreadSafeMethod() {
    m.WaitOne();
    try {
        /* critical code */
    } finally {
        m.ReleaseMutex();
    }
}
嘴硬脾气大 2024-11-10 03:59:26

看起来您为每个线程提供了自己的互斥体。那是行不通的。

在大多数情况下,互斥量是多余的。您只需要:

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

....

lock(syncLock)
{
    // critical section
}

It looks like you give each Thread its own Mutex. That won't work.

And a Mutex is overkill in most situations. You only need:

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

....

lock(syncLock)
{
    // critical section
}
匿名。 2024-11-10 03:59:26

这种模式根本没有锁定。每个线程都会创建一个新的 Mutex 对象并立即拥有它的锁。其他线程本身创建并使用新的互斥体。

考虑使用常规的lock()!

lock(_lockobject) {
   // do inside what needs to be done - executed on a single thread only
} 

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

private object _lockobject; 

编辑:感谢评论者!存在 lock(this) 可能很危险的情况。所以我删除了它。

This pattern does no locking at all. Every thread creates a new Mutex object and immediately owns the lock for it. Other threads create and use a new Mutex itself.

Consider using a regular lock()!

lock(_lockobject) {
   // do inside what needs to be done - executed on a single thread only
} 

where _lockobject is a simple private variable in your class:

private object _lockobject; 

Edit: thanks to the commenters! Situations exist, where lock(this) can be dangerous. So I removed that.

等风来 2024-11-10 03:59:26

互斥体用于识别运行的应用程序实例。

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

Mutex use to identify run app instance.

 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!");
                }
            }
残月升风 2024-11-10 03:59:26

我可以对已接受的答案进行更正吗?

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

May i add a correction to the accepted answer?

private readonly Mutex m = new Mutex();
public void ThreadSafeMethod() {
    while(!m.WaitOne()){}
    try {
        /* critical code */
    } finally {
        m.ReleaseMutex();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文