Pthread互斥锁由不同的线程解锁

时间:2021-04-03 14:14:48

A Naive question ..

一个幼稚的问题. .

I read before saying - "A MUTEX has to be unlocked only by the thread that locked it."

我读了之后说——“一个互斥体只有通过锁住它的线程才能解锁。”

But I have written a program where THREAD1 locks mutexVar and goes for a sleep. Then THREAD2 can directly unlock mutexVar do some operations and return.

但我已经编写了一个程序,其中THREAD1锁住mutexVar并进入睡眠状态。然后,THREAD2可以直接解锁mutexVar进行一些操作并返回。

==> I know everyone say why I am doing so ?? But my question is - Is this a right behaviour of MUTEX ??

我知道大家都说我为什么这么做?但我的问题是——这是互斥的正确行为吗?

==> Adding the sample code

==>添加样例代码。

void *functionC()
{
   pthread_mutex_lock( &mutex1 );
   counter++;
   sleep(10);
   printf("Thread01: Counter value: %d\n",counter);
   pthread_mutex_unlock( &mutex1 );
}

void *functionD()
{
   pthread_mutex_unlock( &mutex1 );
   pthread_mutex_lock( &mutex1 );
   counter=10;
   printf("Counter value: %d\n",counter);
}

int main()
{
   int rc1, rc2;
   pthread_t thread1, thread2;

   if(pthread_mutex_init(&mutex1, NULL))
   printf("Error while using pthread_mutex_init\n");

   if( (rc1=pthread_create( &thread1, NULL, &functionC, NULL)) )
   {   
      printf("Thread creation failed: %d\n", rc1);
   }   

   if( (rc2=pthread_create( &thread2, NULL, &functionD, NULL)) )
   {   
      printf("Thread creation failed: %d\n", rc2);
   } 

3 个解决方案

#1


17  

What you've done is simply not legal, and the behavior is undefined. Mutexes only exclude threads that play by the rules. If you tried to lock mutex1 from thread 2, the thread would be blocked, of course; that's the required thing to do. There's nothing in the spec that says what happens if you try to unlock a mutex you don't own!

你所做的一切根本不合法,行为也没有定义。互斥对象只排除规则执行的线程。如果试图从线程2中锁定mutex1,那么该线程当然会被阻塞;这是必须要做的事情。如果你试图解锁一个你不拥有的互斥体,说明没有任何东西会发生什么!

#2


20  

Pthreads has 3 different kinds of mutexes: Fast mutex, recursive mutex, and error checking mutex. You used a fast mutex which, for performance reasons, will not check for this error. If you use the error checking mutex on Linux you will find you get the results you expect.

Pthreads有三种不同的互斥体:快速互斥体、递归互斥体和错误检查互斥体。您使用了一个快速互斥对象,出于性能原因,它不会检查这个错误。如果您在Linux上使用错误检查互斥锁,您将发现您得到了预期的结果。

Below is a small hack of your program as an example and proof. It locks the mutex in main() and the unlock in the created thread will fail.

下面是你的程序的一个小技巧,作为一个例子和证明。它在main()中锁定互斥对象,创建的线程中的解锁将失败。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>

/*** NOTE THE ATTR INITIALIZER HERE! ***/
pthread_mutex_t mutex1 = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;

int counter = 0;


void *functionD(void* data)
{
   int rc;

   if ((rc = pthread_mutex_unlock(&mutex1)) != 0)
   {
       errno = rc;
       perror("other thread unlock result");
       exit(1);
   }

   pthread_mutex_lock(&mutex1);
   counter=10;
   printf("Thread02: Counter value: %d\n",counter);

   return(data);
}


int main(int argc, char *argv[])
{
   int rc1;
   pthread_t thread1;

   if ((rc1 = pthread_mutex_lock(&mutex1)) != 0)
   {
       errno = rc1;
       perror("main lock result");
   }

   if( (rc1 = pthread_create(&thread1, NULL, &functionD, NULL)))
   {
      printf("Thread creation failed: %d\n", rc1);
   }

   pthread_join(thread1, NULL);
}

#3


-2  

A mutex is used to prevent multiple threads from executing code that is only safe for one thread at a time.

互斥体用于防止多个线程执行一次只对一个线程安全的代码。

To do this a mutex has several features:

为此,互斥对象具有以下几个特性:

  1. A mutex can handle the race conditions associated with multiple threads trying to "lock" the mutex at the same time and always results with one thread winning the race.

    互斥体可以处理与多个试图同时“锁定”互斥体的线程相关的竞争条件,并且总是以一个线程赢得比赛的结果。

  2. Any thread that loses the race gets put to sleep permanently until the mutex is unlocked. The mutex maintains a list of these threads.

    任何输掉比赛的线程都会被永久休眠,直到互斥锁被解锁。互斥体维护这些线程的列表。

  3. A will hand the "lock" to one and only one of the waiting threads when the mutex is unlocked by the thread who was just using it. The mutex will wake that thread.

    当互斥锁被正在使用它的线程解锁时,A将把“锁”交给一个正在等待的线程,而且只有一个线程。互斥体将唤醒该线程。

If that type of pattern is useful for some other purpose then go ahead and use it for a different reason.

如果这种类型的模式对其他目的有用,那么继续使用它,并以不同的理由使用它。

Back to your question. Lets say you were protecting some code from multiple thread accesses with a mutex and lets say 5 threads were waiting while thread A was executing the code. If thread B (not one of the ones waiting since they are permanently slept at the moment) unlocks the mutex, another thread will commence executing the code at the same time as thread A. Probably not desired.

回到你的问题。假设您正在保护一些代码不受互斥对象的多线程访问,假设有5个线程正在等待,而线程a正在执行代码。如果线程B(不是正在等待的线程之一,因为它们正在永久休眠)解锁互斥对象,则另一个线程将开始执行与线程a同时执行的代码。

Maybe if we knew what you were thinking about using the mutex for we could give a better answer. Are you trying to unlock a mutex after a thread was canceled? Do you have code that can handle 2 threads at a time but not three and there is no mutex that lets 2 threads through at a time?

也许如果我们知道你想用互斥体做什么,我们可以给出更好的答案。在线程被取消后,您是否尝试解锁互斥锁?您是否有可以同时处理2个线程而不是3个线程的代码,并且没有一个互斥量可以让2个线程同时通过?

#1


17  

What you've done is simply not legal, and the behavior is undefined. Mutexes only exclude threads that play by the rules. If you tried to lock mutex1 from thread 2, the thread would be blocked, of course; that's the required thing to do. There's nothing in the spec that says what happens if you try to unlock a mutex you don't own!

你所做的一切根本不合法,行为也没有定义。互斥对象只排除规则执行的线程。如果试图从线程2中锁定mutex1,那么该线程当然会被阻塞;这是必须要做的事情。如果你试图解锁一个你不拥有的互斥体,说明没有任何东西会发生什么!

#2


20  

Pthreads has 3 different kinds of mutexes: Fast mutex, recursive mutex, and error checking mutex. You used a fast mutex which, for performance reasons, will not check for this error. If you use the error checking mutex on Linux you will find you get the results you expect.

Pthreads有三种不同的互斥体:快速互斥体、递归互斥体和错误检查互斥体。您使用了一个快速互斥对象,出于性能原因,它不会检查这个错误。如果您在Linux上使用错误检查互斥锁,您将发现您得到了预期的结果。

Below is a small hack of your program as an example and proof. It locks the mutex in main() and the unlock in the created thread will fail.

下面是你的程序的一个小技巧,作为一个例子和证明。它在main()中锁定互斥对象,创建的线程中的解锁将失败。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>

/*** NOTE THE ATTR INITIALIZER HERE! ***/
pthread_mutex_t mutex1 = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;

int counter = 0;


void *functionD(void* data)
{
   int rc;

   if ((rc = pthread_mutex_unlock(&mutex1)) != 0)
   {
       errno = rc;
       perror("other thread unlock result");
       exit(1);
   }

   pthread_mutex_lock(&mutex1);
   counter=10;
   printf("Thread02: Counter value: %d\n",counter);

   return(data);
}


int main(int argc, char *argv[])
{
   int rc1;
   pthread_t thread1;

   if ((rc1 = pthread_mutex_lock(&mutex1)) != 0)
   {
       errno = rc1;
       perror("main lock result");
   }

   if( (rc1 = pthread_create(&thread1, NULL, &functionD, NULL)))
   {
      printf("Thread creation failed: %d\n", rc1);
   }

   pthread_join(thread1, NULL);
}

#3


-2  

A mutex is used to prevent multiple threads from executing code that is only safe for one thread at a time.

互斥体用于防止多个线程执行一次只对一个线程安全的代码。

To do this a mutex has several features:

为此,互斥对象具有以下几个特性:

  1. A mutex can handle the race conditions associated with multiple threads trying to "lock" the mutex at the same time and always results with one thread winning the race.

    互斥体可以处理与多个试图同时“锁定”互斥体的线程相关的竞争条件,并且总是以一个线程赢得比赛的结果。

  2. Any thread that loses the race gets put to sleep permanently until the mutex is unlocked. The mutex maintains a list of these threads.

    任何输掉比赛的线程都会被永久休眠,直到互斥锁被解锁。互斥体维护这些线程的列表。

  3. A will hand the "lock" to one and only one of the waiting threads when the mutex is unlocked by the thread who was just using it. The mutex will wake that thread.

    当互斥锁被正在使用它的线程解锁时,A将把“锁”交给一个正在等待的线程,而且只有一个线程。互斥体将唤醒该线程。

If that type of pattern is useful for some other purpose then go ahead and use it for a different reason.

如果这种类型的模式对其他目的有用,那么继续使用它,并以不同的理由使用它。

Back to your question. Lets say you were protecting some code from multiple thread accesses with a mutex and lets say 5 threads were waiting while thread A was executing the code. If thread B (not one of the ones waiting since they are permanently slept at the moment) unlocks the mutex, another thread will commence executing the code at the same time as thread A. Probably not desired.

回到你的问题。假设您正在保护一些代码不受互斥对象的多线程访问,假设有5个线程正在等待,而线程a正在执行代码。如果线程B(不是正在等待的线程之一,因为它们正在永久休眠)解锁互斥对象,则另一个线程将开始执行与线程a同时执行的代码。

Maybe if we knew what you were thinking about using the mutex for we could give a better answer. Are you trying to unlock a mutex after a thread was canceled? Do you have code that can handle 2 threads at a time but not three and there is no mutex that lets 2 threads through at a time?

也许如果我们知道你想用互斥体做什么,我们可以给出更好的答案。在线程被取消后,您是否尝试解锁互斥锁?您是否有可以同时处理2个线程而不是3个线程的代码,并且没有一个互斥量可以让2个线程同时通过?