繁体   English   中英

pthread_mutex_lock()仅在将返回值分配给变量时起作用,为什么?

[英]pthread_mutex_lock() only works when the return value is assigned to a variable, why?

我正在尝试使用互斥锁而不是信号量,因为我想要信号量行为,但要使用二进制(不计数)。 (也许您会注意到我处于尝试模拟Sleeping Barber算法的早期阶段。)这是我的代码:

#include <stdio.h>
#include <pthread.h>

int main( int argc, char** argv ) {

  int freeSeats = 6;

  pthread_mutexattr_t mutexAttr;
  pthread_mutex_t custWaiting, wrAccess, barberReady;

  pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED);

  pthread_mutex_init(&custWaiting, &mutexAttr);
  pthread_mutex_init(&wrAccess, &mutexAttr);
  pthread_mutex_init(&barberReady, &mutexAttr);

  pthread_mutex_lock(&custWaiting);
  pthread_mutex_lock(&custWaiting);
  pthread_mutex_lock(&custWaiting);

  fprintf(stdout, "got here\n\n");

  return 0;

}

当我第一次执行 ,它会按预期运行(线程被阻塞,命令行挂起,而我的程序等待能够锁定)。 当我终止该程序并再次运行该程序时,它会显示“ got here”(该不该出现)。 为什么这只会在第二次(以及随后的所有尝试)失败而在第一次尝试时失败?

莫名其妙地,如果我修改代码如下(仅init和lock行):

#include <stdio.h>
#include <pthread.h>

int main( int argc, char** argv ) {

  int freeSeats = 6;

  pthread_mutexattr_t mutexAttr;
  pthread_mutex_t custWaiting, wrAccess, barberReady;

  pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED);

  int y = pthread_mutex_init(&custWaiting, &mutexAttr);
  y = pthread_mutex_init(&wrAccess, &mutexAttr);
  y = pthread_mutex_init(&barberReady, &mutexAttr);

  int x = pthread_mutex_lock(&custWaiting);
  x = pthread_mutex_lock(&custWaiting);
  x = pthread_mutex_lock(&custWaiting);

  fprintf(stdout, "got here\n\n");

  return 0;

}

...然后它每次都起作用。 之所以如此令人发疯,是因为我无法检查pthread_mutex_whatever()上的错误代码,因为当我尝试捕获错误代码时它不会失败。 如果我不打算使用返回值,则不希望将它们分配给int 如您所见,我根本没有使用xy 只需为其分配initlock函数的返回值。 那么,为什么这会如此巨大地改变互斥锁的行为呢? 还是我想念其他东西? 我究竟做错了什么?

您应该通过以下方式初始化互斥量:

pthread_mutexattr_init(&mutexAttr);

并设置类型:

pthread_mutexattr_settype(amutexAttr, PTHREAD_MUTEX_NORMAL);

否则,您的代码取决于堆栈内容,并且互斥锁可以是递归类型的,这就是为什么您会看到随机行为的原因。 如果将类型设置为PTHREAD_MUTEX_DEFAULT ,则行为是不确定的,而PTHREAD_MUTEX_NORMAL会给您带来死锁

您要对同一个互斥锁进行三次锁定,这是未定义的行为,除非您声明互斥锁是递归的。 可能是您要锁定三个不同的互斥锁。

未定义的行为意味着任何事情都可能发生,包括您在此处观察到的行为。

要设置互斥锁的属性,必须使用pthread_mutexattr_settype更改互斥锁的属性。 基本上有两种类型可以增强默认行为,即PTHREAD_MUTEX_ERRORCHECKPTHREAD_MUTEX_RECURSIVE 如果您尝试重新锁定,第一个会阻止,第二个可用于多次锁定和解锁。

默认行为是未定义,因为实施此类检查的成本很高。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM