Мьютекс - это концепция программирования, которая часто используется для решения многопоточных задач. Мой вопрос к сообществу:
Что такое мьютекс и как вы его используете?
Мьютекс - это концепция программирования, которая часто используется для решения многопоточных задач. Мой вопрос к сообществу:
Что такое мьютекс и как вы его используете?
Когда у меня начинается большая жаркая дискуссия на работе, я использую резиновый цыпленок, который я держу в своем столе только для таких случаев. Человек, держащий цыпленка, является единственным человеком, которому разрешено говорить. Если вы не держите курицу, вы не можете говорить. Вы можете только указать, что вы хотите цыпленка и ждать, пока не получите его, прежде чем говорить. Как только вы закончите говорить, вы можете передать цыпленка обратно модератору, который передаст его следующему человеку, чтобы поговорить. Это гарантирует, что люди не говорят друг над другом, а также имеют собственное пространство для разговора.
Замените цыпленка с помощью Mutex и человека с помощью нитки, и вы в основном имеете концепцию мьютекса.
Конечно, нет такой вещи, как резиновый мьютекс. Только резиновая курица. У моих кошек когда-то была резиновая мышь, но они ее съели.
Конечно, прежде чем использовать резиновую курятину, вам нужно спросить себя, действительно ли вам нужно 5 человек в одной комнате, и было бы нелегко, если бы один человек в комнате сам делал всю работу. На самом деле, это просто расширяет аналогию, но вы получаете идею.
Mutex - это взаимно исключающий флаг. Он действует как хранитель ворот в раздел кода, разрешающий один поток и блокирующий доступ ко всем остальным. Это гарантирует, что управляемый код будет поражен только одним потоком за раз. Просто обязательно отпустите мьютекс, когда закончите.:)
Взаимное исключение. Здесь находится запись в Википедии:
http://en.wikipedia.org/wiki/Mutual_exclusion
Точка мьютекса - это синхронизация двух потоков. Когда у вас есть два потока, пытающихся получить доступ к одному ресурсу, общий шаблон должен иметь первый блок кода, пытающийся получить доступ, чтобы установить мьютекс перед вводом кода. Когда второй кодовый блок пытается получить доступ, он видит, что mutex установлен и ждет, пока первый блок кода не будет завершен (и не будет установлен мьютекс), а затем продолжит.
Конкретные детали того, как это выполняется, явно сильно варьируются в зависимости от языка программирования.
Когда у вас многопоточное приложение, разные потоки иногда совместно используют общий ресурс, такой как переменная или аналогичный. К этому общему источнику часто нельзя получить доступ одновременно, поэтому необходима конструкция, чтобы гарантировать, что только один поток использует этот ресурс одновременно.
Эта концепция называется "взаимное исключение" (сокращение Mutex) и позволяет гарантировать, что в этой области разрешен только один поток с использованием этого ресурса и т.д.
Как их использовать, зависит от языка, но часто (если не всегда) основывается на мьютексе операционной системы.
Некоторые языки не нуждаются в этой конструкции из-за парадигмы, например, функционального программирования (хорошие примеры - Haskell, ML).
Теперь спросите Google, как их использовать! :)
В С# используется общий мьютекс Monitor. Тип: System.Threading.Monitor '. Он также может использоваться неявно через оператор lock (Object) '. Одним из примеров его использования является построение класса Singleton.
private static readonly Object instanceLock = new Object();
private static MySingleton instance;
public static MySingleton Instance
{
lock(instanceLock)
{
if(instance == null)
{
instance = new MySingleton();
}
return instance;
}
}
Оператор блокировки с использованием объекта private lock создает критический раздел. Требование, чтобы каждый поток ожидал завершения предыдущего. Первый поток войдет в раздел и инициализирует экземпляр. Второй поток будет ждать, попасть в раздел и получить инициализированный экземпляр.
Любая синхронизация статического члена может также использовать оператор блокировки.
Чтобы сначала понять MUTEX, вам нужно знать, что такое "состояние гонки", а затем только вы поймете, зачем нужен MUTEX. Предположим, у вас есть многопоточная программа, и у вас есть два потока. Теперь у вас есть одно задание в очереди заданий. Первый поток проверяет очередь заданий и после того, как он найдет задание, он начнет его выполнять. Второй поток также проверяет очередь заданий и обнаруживает, что в очереди есть одно задание. Таким образом, он также назначит один и тот же указатель на работу. Итак, теперь, что происходит, оба потока выполняют одну и ту же работу. Это вызовет ошибку сегментации. Это пример состояния гонки.
Решение этой проблемы - MUTEX. MUTEX - это своего рода замок, который блокирует один поток за раз. Если другой поток хочет заблокировать его, поток просто блокируется.
Ссылка MUTEX в этом файле PDF действительно стоит прочитать.
Что такое мьютекс?
Мьютекс (фактически термин мьютекс - это сокращение от взаимного исключения), также известный как спин-блокировка, является самым простым инструментом синхронизации, который используется для защиты критических областей и, таким образом, предотвращения условий гонки. То есть поток должен получить блокировку перед входом в критический раздел (в критическом разделе несколько потоков совместно используют общую переменную, обновление таблицы, запись файла и т.д.), Он снимает блокировку, когда покидает критический раздел.
Что такое состояние гонки?
Состояние гонки возникает, когда два или более потоков могут получить доступ к общим данным, и они пытаются изменить их одновременно. Поскольку алгоритм планирования потоков может переключаться между потоками в любое время, вы не знаете порядок, в котором потоки будут пытаться получить доступ к общим данным. Следовательно, результат изменения данных зависит от алгоритма планирования потоков, то есть оба потока "участвуют в гонке", чтобы получить доступ/изменить данные.
Пример из реальной жизни:
Когда на работе я веду бурную дискуссию, я использую резинового цыпленка, которого держу в своем столе именно для таких случаев. Человек, держащий курицу, является единственным человеком, которому разрешено говорить. Если вы не держите курицу, вы не можете говорить. Вы можете только указать, что хотите курицу, и подождать, пока вы ее получите, прежде чем говорить. Как только вы закончите говорить, вы можете вернуть курицу модератору, который передаст ее следующему человеку, который будет говорить. Это гарантирует, что люди не разговаривают друг с другом, а также имеют свое собственное пространство для общения.
Замените Цыпленка на Мьютекс, а человека - на нить, и у вас в основном будет концепция мьютекса.
@Xetius
Использование в С#:
В этом примере показано, как локальный объект Mutex используется для синхронизации доступа к защищенному ресурсу. Поскольку каждый вызывающий поток блокируется до тех пор, пока не получит право собственности на мьютекс, он должен вызвать метод ReleaseMutex, чтобы освободить право собственности на поток.
using System;
using System.Threading;
class Example
{
// Create a new Mutex. The creating thread does not own the mutex.
private static Mutex mut = new Mutex();
private const int numIterations = 1;
private const int numThreads = 3;
static void Main()
{
// Create the threads that will use the protected resource.
for(int i = 0; i < numThreads; i++)
{
Thread newThread = new Thread(new ThreadStart(ThreadProc));
newThread.Name = String.Format("Thread{0}", i + 1);
newThread.Start();
}
// The main thread exits, but the application continues to
// run until all foreground threads have exited.
}
private static void ThreadProc()
{
for(int i = 0; i < numIterations; i++)
{
UseResource();
}
}
// This method represents a resource that must be synchronized
// so that only one thread at a time can enter.
private static void UseResource()
{
// Wait until it is safe to enter.
Console.WriteLine("{0} is requesting the mutex",
Thread.CurrentThread.Name);
mut.WaitOne();
Console.WriteLine("{0} has entered the protected area",
Thread.CurrentThread.Name);
// Place code to access non-reentrant resources here.
// Simulate some work.
Thread.Sleep(500);
Console.WriteLine("{0} is leaving the protected area",
Thread.CurrentThread.Name);
// Release the Mutex.
mut.ReleaseMutex();
Console.WriteLine("{0} has released the mutex",
Thread.CurrentThread.Name);
}
}
// The example displays output like the following:
// Thread1 is requesting the mutex
// Thread2 is requesting the mutex
// Thread1 has entered the protected area
// Thread3 is requesting the mutex
// Thread1 is leaving the protected area
// Thread1 has released the mutex
// Thread3 has entered the protected area
// Thread3 is leaving the protected area
// Thread3 has released the mutex
// Thread2 has entered the protected area
// Thread2 is leaving the protected area
// Thread2 has released the mutex
Здесь есть отличные ответы, вот еще одна большая аналогия для объяснения того, что мьютекс:
Рассмотрим одиночный туалет с ключом. Когда кто-то входит, они берут ключ, а туалет занят. Если кому-то еще нужно пользоваться туалетом, им нужно ждать в очереди. Когда человек в туалете закончен, они передают ключ следующему человеку в очереди. Имеете смысл, правильно?
Преобразуйте туалет в историю в общий ресурс и ключ к мьютексу. Взять ключ в туалет (приобрести замок) позволяет использовать его. Если ключ отсутствует (блокировка заблокирована), вам нужно подождать. Когда ключ возвращается человеком (отпустите блокировку), вы сможете его приобрести сейчас.
Мьютексы полезны в ситуациях, когда вам необходимо обеспечить эксклюзивный доступ к ресурсу через несколько процессов, где регулярная блокировка не поможет, поскольку она работает только с потоками.