Использование Mutex в c # - PullRequest
       25

Использование Mutex в c #

30 голосов
/ 22 апреля 2011

Я немного новичок в работе с потоками в 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();
     }


    } 

Ответы [ 4 ]

56 голосов
/ 22 апреля 2011

Проблема здесь в том, что все ваши абоненты используют другой мьютекс;вам нужно, чтобы блокирующий объект был shared , обычно делая его полем.Например, и переключение на более простую метафору 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();
    }
}
5 голосов
/ 22 апреля 2011

Похоже, вы даете каждой теме свой собственный мьютекс. Это не сработает.

А мьютекс в большинстве ситуаций избыточен. Вам нужно только:

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

....

lock(syncLock)
{
    // critical section
}
5 голосов
/ 22 апреля 2011

Этот шаблон вообще не блокируется. Каждый поток создает новый объект Mutex и сразу же получает блокировку для него. Другие темы сами создают и используют новый Mutex.

Подумайте об использовании обычной блокировки ()!

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

где _lockobject - простая личная переменная в вашем классе:

private object _lockobject; 

Редактировать: спасибо комментаторам! Существуют ситуации, когда блокировка (это) может быть опасной. Так что я убрал это.

1 голос
/ 29 августа 2018

Использование 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!");
                }
            }
...