multithreading 什么是互斥锁?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34524/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 00:58:20  来源:igfitidea点击:

What is a mutex?

multithreadingconcurrencymutex

提问by bmurphy1976

A mutex is a programming concept that is frequently used to solve multi-threading problems. My question to the community:

互斥锁是一种经常用于解决多线程问题的编程概念。我对社区的问题:

What is a mutex and how do you use it?

什么是互斥锁以及如何使用它?

回答by Xetius

When I am having a big heated discussion at work, I use a rubber chicken which I keep in my desk for just such occasions. The person holding the chicken is the only person who is allowed to talk. If you don't hold the chicken you cannot speak. You can only indicate that you want the chicken and wait until you get it before you speak. Once you have finished speaking, you can hand the chicken back to the moderator who will hand it to the next person to speak. This ensures that people do not speak over each other, and also have their own space to talk.

当我在工作中进行激烈的讨论时,我会使用一只橡皮鸡,我放在办公桌上就是为了这种场合。拿着鸡的人是唯一被允许说话的人。如果你不拿着鸡,你就不能说话。你只能表明你想要鸡肉,等到你得到它再说话。一旦你说完,你可以把鸡交还给主持人,主持人将把它交给下一个发言的人。这确保了人们不会互相交谈,并且也有自己的谈话空间。

Replace Chicken with Mutex and person with thread and you basically have the concept of a mutex.

用互斥体替换鸡,用线程替换人,你基本上有了互斥体的概念。

Of course, there is no such thing as a rubber mutex. Only rubber chicken. My cats once had a rubber mouse, but they ate it.

当然,没有橡胶互斥锁这样的东西。只有橡胶鸡。我的猫曾经有一只橡皮老鼠,但他们吃了它。

Of course, before you use the rubber chicken, you need to ask yourself whether you actually need 5 people in one room and would it not just be easier with one person in the room on their own doing all the work. Actually, this is just extending the analogy, but you get the idea.

当然,在你使用橡皮鸡之前,你需要问问自己,你是否真的需要一个房间里的5个人,一个人在一个房间里自己做所有的工作会不会更容易。实际上,这只是类比的延伸,但您明白了。

回答by Craig

A Mutex is a mutually exclusive flag. It acts as a gate keeper to a section of code allowing one thread in and blocking access to all others. This ensures that the code being controled will only be hit by a single thread at a time. Just be sure to release the mutex when you are done. :)

Mutex 是一个互斥标志。它充当一段代码的看门人,允许一个线程进入并阻止对所有其他线程的访问。这确保了被控制的代码一次只会被一个线程命中。完成后一定要释放互斥锁。:)

回答by TheSmurf

Mutual Exclusion. Here's the Wikipedia entry on it:

相互排斥。这是关于它的维基百科条目:

http://en.wikipedia.org/wiki/Mutual_exclusion

http://en.wikipedia.org/wiki/Mutual_exclusion

The point of a mutex is to synchronize two threads. When you have two threads attempting to access a single resource, the general pattern is to have the first block of code attempting access to set the mutex before entering the code. When the second code block attempts access, it sees the mutex is set and waits until the first block of code is complete (and un-sets the mutex), then continues.

互斥锁的目的是同步两个线程。当您有两个线程尝试访问单个资源时,一般模式是让第一个代码块尝试访问以在输入代码之前设置互斥锁。当第二个代码块尝试访问时,它看到互斥体已设置并等待,直到第一个代码块完成(并取消设置互斥体),然后继续。

Specific details of how this is accomplished obviously varies greatly by programming language.

如何实现这一点的具体细节显然因编程语言而异。

回答by Mats Fredriksson

When you have a multi-threaded application, the different threads sometimes share a common resource, such as a variable or similar. This shared source often cannot be accessed at the same time, so a construct is needed to ensure that only one thread is using that resource at a time.

当您有一个多线程应用程序时,不同的线程有时会共享一个公共资源,例如变量或类似资源。此共享源通常无法同时访问,因此需要一种构造以确保一次只有一个线程正在使用该资源。

The concept is called "mutual exclusion" (short Mutex), and is a way to ensure that only one thread is allowed inside that area, using that resource etc.

这个概念被称为“互斥”(简称互斥),是一种确保在该区域内只允许一个线程使用该资源等的方法。

How to use them is language specific, but is often (if not always) based on a operating system mutex.

如何使用它们是特定于语言的,但通常(如果不是总是)基于操作系统互斥锁。

Some languages doesn't need this construct, due to the paradigm, for example functional programming (Haskell, ML are good examples).

由于范式的原因,某些语言不需要这种构造,例如函数式编程(Haskell、ML 是很好的例子)。

回答by Anthony Mastrean

In C#, the common mutex used is the Monitor. The type is 'System.Threading.Monitor'. It may also be used implicitly via the 'lock(Object)' statement. One example of its use is when constructing a Singleton class.

在 C# 中,常用的互斥锁是Monitor。类型是“ System.Threading.Monitor”。它也可以通过' lock(Object)'语句隐式使用。其使用示例之一是在构造单例类时。

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;
    }
}

The lock statement using the private lock object creates a critical section. Requiring each thread to wait until the previous is finished. The first thread will enter the section and initialize the instance. The second thread will wait, get into the section, and get the initialized instance.

使用私有锁对象的 lock 语句创建了一个临界区。要求每个线程等待前一个线程完成。第一个线程将进入该部分并初始化该实例。第二个线程将等待,进入该部分,并获取初始化的实例。

Any sort of synchronization of a static member may use the lock statement similarly.

静态成员的任何类型的同步都可以类似地使用 lock 语句。

回答by habib

What is a Mutex?

什么是互斥锁

The mutex (In fact, the term mutex is short for mutual exclusion) also known as spinlock is the simplest synchronization tool that is used to protect critical regions and thus prevent race conditions. That is a thread must acquire a lock before entering into a critical section (In critical section multi threads share a common variable, updating a table, writing a file and so on), it releases the lock when it leaves critical section.

互斥(实际上,互斥是互斥的缩写)也称为自旋锁,是最简单的同步工具,用于保护关键区域,从而防止竞争条件。即线程在进入临界区之前必须获得锁(在临界区中,多线程共享一个公共变量,更新表,写入文件等),它在离开临界区时释放锁。

What is a Race Condition?

什么是竞争条件

A race condition occurs when two or more threads can access shared data and they try to change it at the same time. Because the thread scheduling algorithm can swap between threads at any time, you don't know the order in which the threads will attempt to access the shared data. Therefore, the result of the change in data is dependent on the thread scheduling algorithm, i.e. both threads are "racing" to access/change the data.

当两个或多个线程可以访问共享数据并尝试同时更改它时,就会发生竞争条件。由于线程调度算法可以随时在线程之间交换,因此您不知道线程尝试访问共享数据的顺序。因此,数据变化的结果取决于线程调度算法,即两个线程都在“竞相”访问/更改数据。

Real life example:

现实生活中的例子:

When I am having a big heated discussion at work, I use a rubber chicken which I keep in my desk for just such occasions. The person holding the chicken is the only person who is allowed to talk. If you don't hold the chicken you cannot speak. You can only indicate that you want the chicken and wait until you get it before you speak. Once you have finished speaking, you can hand the chicken back to the moderator who will hand it to the next person to speak. This ensures that people do not speak over each other, and also have their own space to talk.

Replace Chicken with Mutex and person with thread and you basically have the concept of a mutex.

@Xetius

当我在工作中进行激烈的讨论时,我会使用一只橡皮鸡,我放在办公桌上就是为了这种场合。拿着鸡的人是唯一被允许说话的人。如果你不拿着鸡,你就不能说话。你只能表明你想要鸡肉,等到你得到它再说话。一旦你说完,你可以把鸡交还给主持人,主持人将把它交给下一个发言的人。这确保了人们不会互相交谈,并且也有自己的谈话空间。

用互斥体替换鸡,用线程替换人,你基本上有了互斥体的概念。

@Xetius

Usage in C#:

C# 中的用法:

This example shows how a local Mutex object is used to synchronize access to a protected resource. Because each calling thread is blocked until it acquires ownership of the mutex, it must call the ReleaseMutex method to release ownership of the thread.

此示例说明如何使用本地互斥对象来同步对受保护资源的访问。因为每个调用线程在获得互斥锁的所有权之前都会被阻塞,所以它必须调用 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

MSDN Reference Mutex

MSDN 参考互斥体

回答by Chen A.

There are some great answers here, here is another great analogy for explaining what mutexis:

这里有一些很好的答案,这里有另一个很好的类比来解释互斥锁是什么:

Consider singletoilet with a key. When someone enters, they take the key and the toilet is occupied. If someone else needs to use the toilet, they need to wait in a queue. When the person in the toilet is done, they pass the key to the next person in queue. Make sense, right?

考虑带钥匙的单人马桶。当有人进入时,他们拿了钥匙,厕所被占用了。如果其他人需要使用厕所,他们需要排队等候。当厕所里的人完成后,他们将钥匙传递给排队的下一个人。有道理吧?

Convert the toiletin the story to a shared resource, and the keyto a mutex. Taking the key to the toilet (acquire a lock) permits you to use it. If there is no key (the lock is locked) you have to wait. When the key is returned by the person (release the lock) you're free to acquire it now.

将故事中的厕所转换为共享资源,并将钥匙转换为互斥锁。拿上厕所的钥匙(获得一把锁)允许您使用它。如果没有钥匙(锁被锁定),您必须等待。当钥匙由人归还(释放锁)时,您现在可以自由获取它。

回答by user3751012

To understand MUTEX at first you need to know what is "race condition" and then only you will understand why MUTEX is needed. Suppose you have a multi-threading program and you have two threads. Now, you have one job in the job queue. The first thread will check the job queue and after finding the job it will start executing it. The second thread will also check the job queue and find that there is one job in the queue. So, it will also assign the same job pointer. So, now what happens, both the threads are executing the same job. This will cause a segmentation fault. This is the example of a race condition.

要首先了解 MUTEX,您需要知道什么是“竞争条件”,然后只有您才会明白为什么需要 MUTEX。假设您有一个多线程程序并且您有两个线程。现在,您的作业队列中有一项作业。第一个线程将检查作业队列,并在找到作业后开始执行它。第二个线程也会检查作业队列,发现队列中有一个作业。因此,它也会分配相同的作业指针。那么,现在发生了什么,两个线程都在执行相同的工作。这将导致分段错误。这是竞争条件的示例。

The solution to this problem is MUTEX. MUTEX is a kind of lock which locks one thread at a time. If another thread wants to lock it, the thread simply gets blocked.

这个问题的解决方案是 MUTEX。MUTEX 是一种锁,一次锁定一个线程。如果另一个线程想要锁定它,该线程只会被阻塞。

The MUTEX topic in this pdf filelink is really worth reading.

这个pdf文件链接中的MUTEX主题真的很值得一读。

回答by 18hrs

Mutexes are useful in situations where you need to enforce exclusive access to a resource accross multiple processes, where a regular lock won't help since it only works accross threads.

互斥锁在您需要强制跨多个进程对资源进行独占访问的情况下很有用,在这种情况下,常规锁无济于事,因为它只能跨线程工作。

回答by Sandeep_black

Mutex: Mutex stands for Mutual Exclusion. It means at a time one process/thread can enter into critical section. In concurrent programming where multiple threads/process tries to update the shared resource (any variable, shared memory etc.) may lead some unexpected result. ( As the result depends upon the which thread/process gets the first access).

互斥:互斥代表MUTUAL防爆clusion。这意味着一次一个进程/线程可以进入临界区。在多个线程/进程尝试更新共享资源(任何变量、共享内存等)的并发编程中,可能会导致一些意想不到的结果。(结果取决于哪个线程/进程获得第一次访问)。

In order to avoid such an unexpected result we need some synchronization mechanism, which ensures that only one thread/process gets access to such a resource at a time.

为了避免这种意外的结果,我们需要一些同步机制,以确保一次只有一个线程/进程可以访问这样的资源。

pthread library provides support for Mutex.

pthread 库提供对互斥锁的支持。

typedef union
{
  struct __pthread_mutex_s
  {
    ***int __lock;***
    unsigned int __count;
    int __owner;
#ifdef __x86_64__
    unsigned int __nusers;
#endif
 int __kind;
#ifdef __x86_64__
    short __spins;
    short __elision;
    __pthread_list_t __list;
# define __PTHREAD_MUTEX_HAVE_PREV      1
# define __PTHREAD_SPINS             0, 0
#else
    unsigned int __nusers;
    __extension__ union
    {
      struct
      {
        short __espins;
        short __elision;
# define __spins __elision_data.__espins
# define __elision __elision_data.__elision
# define __PTHREAD_SPINS         { 0, 0 }
      } __elision_data;
      __pthread_slist_t __list;
    };
#endif

This is the structure for mutex data type i.e pthread_mutex_t. When mutex is locked, __lock set to 1. When it is unlocked __lock set to 0.

这是互斥数据类型的结构,即 pthread_mutex_t。当互斥锁被锁定时,__lock 设置为 1。当它被解锁时 __lock 设置为 0。

This ensure that no two processes/threads can access the critical section at same time.

这确保没有两个进程/线程可以同时访问临界区。