Pthread Mutex锁通过不同的线程解锁

cod*_*eak 15 linux mutex pthreads

天真的问题......

我之前读过 - " 只有通过锁定它的线程才能解锁MUTEX. "

但是我写了一个程序,其中THREAD1锁定了mutexVar并进入睡眠状态.然后THREAD2可以直接解锁mutexVar做一些操作并返回.

==>我知道每个人都说我为什么这样做?但我的问题是 - 这是MUTEX的正确行为吗?

==>添加示例代码

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);
   } 
Run Code Online (Sandbox Code Playgroud)

Duc*_*uck 23

Pthreads有3种不同的互斥体:快速互斥体,递归互斥体和错误检查互斥体.您使用了一个快速互斥锁,出于性能原因,它不会检查此错误.如果您在Linux上使用错误检查互斥锁,您会发现您获得了预期的结果.

以下是您的程序的一个小黑客作为示例和证明.它锁定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);
}
Run Code Online (Sandbox Code Playgroud)

  • 在Linux上使用-D_GNU_SOURCE进行编译. (3认同)

Ern*_*ill 20

你所做的只是不合法,行为是不明确的.互斥锁仅排除规则播放的线程.如果你试图从线程2锁定mutex1,那么线程当然会被阻塞; 这是必需的事情.规范中没有任何内容说明如果您尝试解锁不属于您的互斥锁会发生什么!

  • @codingfreak:API不是一件紧身衣.文档说"不要那样做",而不是"我们会主动阻止你这样做".计算机并不总是阻止你做你不应该做的事情.这是一个相当基本的概念,当你学习时会一次又一次地出现:你可以做各种各样的事情,其中​​很多是你不应该做的事情,如果你做的话,它们有不确定的行为.这就像说"你不允许开醉" - 没有机制可以阻止你这样做,但你仍然不应该这样做. (27认同)