ChatGPT解决这个技术问题 Extra ChatGPT

What is a mutex?

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?

Here's a good article on the difference: barrgroup.com/Embedded-Systems/How-To/RTOS-Mutex-Semaphore
A tutorial on mutex can help clear things up: stackoverflow.com/questions/4989451/mutex-example-tutorial
A mutex is like a bathroom key at a gas station, ensuring that only one person may use the bathroom at a time AND that no one else may use the toilet until the current occupant is finished and the key is returned.

i
iwasrobbed

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.


@SirYakalot, you mean the chicken is the resource, and the moderator is the mutex?
The chicken is the mutex. People hoilding the mu.. chicken are competing threads. The Moderator is the OS. When people requests the chicken, they do a lock request. When you call mutex.lock(), your thread stalls in lock() and makes a lock request to the OS. When the OS detects that the mutex was released from a thread, it merely gives it to you, and lock() returns - the mutex is now yours and only yours. Nobody else can steal it, because calling lock() will block him. There is also try_lock() that will block and return true when mutex is yours and immediately false if mutex is in use.
Sometimes the origin of some programming concepts is unclear. A newbie might go around wondering why everyone is talking about regex. It isn't apparent that regex is short for [reg]ular [ex]pression. Similarly, mutex is short for [mut]ual [ex]clusion. This might make the meaning of the term easier to digest. @TheSmurf linked to it in their answer, but it might be good to add it here for historical purposes.
"Of course, there is no such thing as a rubber mutex." Thanks for clarifying.
The best answer I have ever seen on stackoverflow, elegant.
v
vnilla

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 controlled will only be hit by a single thread at a time. Just be sure to release the mutex when you are done. :)


A mutex has nothing to do with a section of code per se, it protects some resource. That resource may be a code segment if the mutex is only ever used around that code but, the minute you start using the mutex in multiple places in your code, your explanation fails. Typically it can also be used to protect some data structure, which may be accessed from many places in the code.
@paxdiablo: allow me to disagree. You can have 2 pieces of code, one using the Mutex, the other doesn't. You access the data structure from both pieces of code. How does the Mutex protect the data structure? It doesn't. You will have data races as if no Mutex was in place at all.
@Thomas, then your code has a bug. To say the mutex doesn't protect the data because you're not using the mutex at one of the points you need to is no different than saying your home security is deficient because, on Thursdays, you leave the front door unlocked and open when you go to work :-)
@paxdiablo: that's my point: the developer has to follow a convention that he only accesses the data structure using code that is protected by the Mutex. The Mutex protects the code. It does not protect the data structure. I would say my home security is useless if I regularly leave the door open. I then have implemented it the wrong way, like I implemented code the wrong way.
@Thomas, I suspect it's going to just come down to semantics. Forgetting to use a mutex to protect data is, in my view, no different to forgetting to use it to protect code. You've forgotten to protect it at some point, hilarity will ensue :-) I can see your viewpoint but I have to stand by my description because there's usually no problem at all with multiple threads running the same code, since the code itself doesn't change underneath them. It's only when the data changes unexpectedly will they run into trouble.
P
Pang

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

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 that the mutex is set and waits until the first block of code is complete (and unsets the mutex), then continues.

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


N
Neurotransmitter

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).


C
Community

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

Usage in 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.

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


How is Mutex implemented though? Is it hardware based? Does it have some waiting mechanism to make sure all threads know what is the current state?
C
Chen A.

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

Consider single toilet 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 toilet in the story to a shared resource, and the key to 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.


But the c# example does not support support your queue assertion, "pass the key to the next person in queue". The example is demonstrating a stack or random. 1, 2, & 3 all request access, in that sequence. One is first allowed into the protected area, and then three is allowed. A queue would have given it to the second.
I wasn't referring any concrete implementation, or concrete programming language. My example relates to high level abstraction of mutex as a principle.
R
Radiodef

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.

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.

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


This is an implementation dependent answer. Also, In CS a monitor is different than mutex. Monitors has a synchronization mechanism but mutex just lock the thing until no longer needed. IDK about implementation details or C# semantics, but I think the context of the question is broader
u
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.

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.

The MUTEX topic in this pdf file link is really worth reading.


By "MUTEX topic" you meant the section on semaphores, because its examples are of binary semaphores, right?
well a Mutex is just a semaphore with value 1
What is the name of the book of that chapter you shared? Please
@OmarFaroqueAnik the book referenced is Advanced Linux Programming by CodeSourcery LLC, published by New Riders Publishing and can be accessed from the linked domain's home page.
To understand "segmentation fault" at first you need to know what is...
1
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.


Is that really true? Wont individual processes create their own mutex copy?
C
Community

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

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.

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.

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