在另一个线程中,pthread_mutex_lock和pthread_mutex_lock。

时间:2020-11-25 14:14:11

I called a pthread_mutex_lock(&th) in a thread then I want to unlock the mutex in another thread pthread_mutex_unlock(&th)

我在一个线程中调用了pthread_mutex_lock(&th)然后我想在另一个线程pthread_mutex_unlock(&th)中解锁互斥

Is it possible to do that?

有可能做到吗?

Or the mutex should be unlocked in the same thread ?

或者互斥锁应该在同一个线程中解锁?

3 个解决方案

#1


3  

It should be unlocked in the same thread. From the man page: "If a thread attempts to unlock a mutex that it has not locked or a mutex which is unlocked, undefined behavior results." (http://pubs.opengroup.org/onlinepubs/009604499/functions/pthread_mutex_lock.html)

它应该在同一个线程中解锁。如果线程试图解锁未锁定的互斥对象或未锁定的互斥对象,则会导致未定义的行为。(http://pubs.opengroup.org/onlinepubs/009604499/functions/pthread_mutex_lock.html)

#2


2  

I just wanted to add to Guijt's answer: When a thread locks a mutex, it is assumed it is inside a critical section. If we allow another thread to unlock that mutex, the first thread might still be inside the critical section, resulting in problems.

我只是想补充一下Guijt的答案:当一个线程锁住一个互斥对象时,假设它在一个关键部分中。如果我们允许另一个线程解锁那个互斥对象,第一个线程可能仍然在关键部分中,从而导致问题。

I can see several solutions to your problem:

我可以看到你的问题的几个解决方案:

Option 1: Rethink your algorithm

选项1:重新考虑你的算法。

Try to understand why you need to unlock from a different thread, and see if you can get the unlocking to be done within the locking thread. This is the best solution, as it typically produces the code that is simplest to understand, and simplest to prove it is actually doing what you believe it is doing. With multithreaded programming being so complicated, the price it is worth paying for such simplicity should be quite high.

尝试理解为什么需要从不同的线程中解锁,并看看是否可以在锁线程中解锁。这是最好的解决方案,因为它通常生成的代码最容易理解,也最容易证明它实际上正在做您认为它正在做的事情。由于多线程编程非常复杂,因此为这种简单性付出的代价应该是相当高的。

Option 2: Synchronize the threads with an event

选项2:将线程与事件同步

One might argue it is just a method to implement option 1 above. The idea is that when the locking thread finishes with the critical section, it does not go out to do whatever, but waits on an event. When the second thread wishes to release the lock, it instead signals the event. The first thread then releases the lock.

有人可能会说,这只是实现上述选项1的一种方法。其思想是,当锁定线程完成关键部分时,它不会出去做任何事情,而是等待一个事件。当第二个线程希望释放锁时,它会向事件发出信号。第一个线程然后释放锁。

This procedure has the advantage that thread 2 cannot inadvertently release the lock too soon.

这个过程的优点是线程2不能过早地不经意地释放锁。

Option 3: Don't use a mutex

选项3:不要使用互斥对象。

If neither one of the above options work for you, you most likely are not using the mutex for mutual exclusion, but for synchronizations. If such is the case, you are likely using the wrong construct.

如果上面的选项中没有一个对您不起作用,那么您很可能不会使用互斥对象来进行互斥,而是使用互斥对象来进行同步。如果是这样,那么您可能使用了错误的构造。

The construct most resembling a mutex is a semaphore. In fact, for years the Linux kernel did not have a mutex, claiming that it's just a semaphore with a maximal value of 1. A semaphore, unlike a mutex, does not require that the same thread lock and release.

与互斥体最相似的构造是信号量。事实上,多年来Linux内核都没有互斥,声称它只是一个最大值为1的信号量。与互斥对象不同,信号量不需要相同的线程锁和释放。

RTFM on sem_init and friends for how to use it.

RTFM上的sem_init和朋友如何使用它。

Please be reminded that you must first model your problem, and only then choose the correct synchronization construct to use. If you do it the other way around, you are almost certain to introduce lots of bugs that are really really really difficult to find and fix.

请注意,您必须首先对您的问题建模,然后才选择要使用的正确的同步构造。如果你用另一种方法来做,你几乎肯定会引入很多非常难以发现和修复的bug。

#3


0  

Whole purpose of using Mutex is achieve mutual exclusion in a critical section with ownership being tracked by the kernel. So mutex has to be unlocked in the same thread which has acquired it

使用互斥锁的整个目的是在一个关键部分实现互斥,而所有权被内核跟踪。因此,互斥锁必须在获得它的同一线程中被解锁。

#1


3  

It should be unlocked in the same thread. From the man page: "If a thread attempts to unlock a mutex that it has not locked or a mutex which is unlocked, undefined behavior results." (http://pubs.opengroup.org/onlinepubs/009604499/functions/pthread_mutex_lock.html)

它应该在同一个线程中解锁。如果线程试图解锁未锁定的互斥对象或未锁定的互斥对象,则会导致未定义的行为。(http://pubs.opengroup.org/onlinepubs/009604499/functions/pthread_mutex_lock.html)

#2


2  

I just wanted to add to Guijt's answer: When a thread locks a mutex, it is assumed it is inside a critical section. If we allow another thread to unlock that mutex, the first thread might still be inside the critical section, resulting in problems.

我只是想补充一下Guijt的答案:当一个线程锁住一个互斥对象时,假设它在一个关键部分中。如果我们允许另一个线程解锁那个互斥对象,第一个线程可能仍然在关键部分中,从而导致问题。

I can see several solutions to your problem:

我可以看到你的问题的几个解决方案:

Option 1: Rethink your algorithm

选项1:重新考虑你的算法。

Try to understand why you need to unlock from a different thread, and see if you can get the unlocking to be done within the locking thread. This is the best solution, as it typically produces the code that is simplest to understand, and simplest to prove it is actually doing what you believe it is doing. With multithreaded programming being so complicated, the price it is worth paying for such simplicity should be quite high.

尝试理解为什么需要从不同的线程中解锁,并看看是否可以在锁线程中解锁。这是最好的解决方案,因为它通常生成的代码最容易理解,也最容易证明它实际上正在做您认为它正在做的事情。由于多线程编程非常复杂,因此为这种简单性付出的代价应该是相当高的。

Option 2: Synchronize the threads with an event

选项2:将线程与事件同步

One might argue it is just a method to implement option 1 above. The idea is that when the locking thread finishes with the critical section, it does not go out to do whatever, but waits on an event. When the second thread wishes to release the lock, it instead signals the event. The first thread then releases the lock.

有人可能会说,这只是实现上述选项1的一种方法。其思想是,当锁定线程完成关键部分时,它不会出去做任何事情,而是等待一个事件。当第二个线程希望释放锁时,它会向事件发出信号。第一个线程然后释放锁。

This procedure has the advantage that thread 2 cannot inadvertently release the lock too soon.

这个过程的优点是线程2不能过早地不经意地释放锁。

Option 3: Don't use a mutex

选项3:不要使用互斥对象。

If neither one of the above options work for you, you most likely are not using the mutex for mutual exclusion, but for synchronizations. If such is the case, you are likely using the wrong construct.

如果上面的选项中没有一个对您不起作用,那么您很可能不会使用互斥对象来进行互斥,而是使用互斥对象来进行同步。如果是这样,那么您可能使用了错误的构造。

The construct most resembling a mutex is a semaphore. In fact, for years the Linux kernel did not have a mutex, claiming that it's just a semaphore with a maximal value of 1. A semaphore, unlike a mutex, does not require that the same thread lock and release.

与互斥体最相似的构造是信号量。事实上,多年来Linux内核都没有互斥,声称它只是一个最大值为1的信号量。与互斥对象不同,信号量不需要相同的线程锁和释放。

RTFM on sem_init and friends for how to use it.

RTFM上的sem_init和朋友如何使用它。

Please be reminded that you must first model your problem, and only then choose the correct synchronization construct to use. If you do it the other way around, you are almost certain to introduce lots of bugs that are really really really difficult to find and fix.

请注意,您必须首先对您的问题建模,然后才选择要使用的正确的同步构造。如果你用另一种方法来做,你几乎肯定会引入很多非常难以发现和修复的bug。

#3


0  

Whole purpose of using Mutex is achieve mutual exclusion in a critical section with ownership being tracked by the kernel. So mutex has to be unlocked in the same thread which has acquired it

使用互斥锁的整个目的是在一个关键部分实现互斥,而所有权被内核跟踪。因此,互斥锁必须在获得它的同一线程中被解锁。