我知道这个问题听起来很熟悉,甚至可能是个愚蠢的问题,但我没能找到解决办法.

所以我的问题基本上是,当一个parent_thread调用pthread_mutex_lock(&mutex),然后调用pthread_cond_wait(&condition, &mutex)释放互斥锁,然后child_thread调用pthread_mutex_lock(&mutex),然后是pthread_cond_signal(&condition),然后是pthread_mutex_unlock(&mutex)时会发生什么.这意味着互斥锁被解锁,现在如果parent_thread次try 调用pthread_mutex_unlock(&mutex),应该会导致未定义的行为,对吗?

示例代码:

pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t c = PTHREAD_COND_INITIALIZER;

void thr_exit() {
  pthread_mutex_lock(&m);
  done = 1;
  pthread_cond_signal(&c);
  pthread_mutex_unlock(&m);
}

void *child(void *arg) {
  printf("child\n");
  thr_exit();
  return NULL;
} 
void thr_join() {
  pthread_mutex_lock(&m);
  while (done == 0)
  pthread_cond_wait(&c, &m); 
  pthread_mutex_unlock(&m); 
}

int main(int argc, char *argv[]) {
  printf("parent: begin\n"); 
  pthread_t p;
  pthread_create(&p, NULL, child, NULL);
  thr_join();
  printf("parent: end\n"); return 0;
}

推荐答案

对不起,只有在我发表 comments 时才读你的标题.为了确保我理解您的操作顺序,我已经发布了一个冗长的答案:

父调用:

pthread_mutex_lock(&m); // locks the mutex
pthread_cond_wait(&c, &m);  // releases the mutex

子级呼叫:

pthread_mutex_lock(&m);  // locks the mutex
pthread_cond_signal(&c); // does nothing to the mutex, it's still locked
// the parent thread has been signaled, but it is still blocked
// because it can't acquire the mutex.
// At this moment in time, the child still owns the mutex, so
// pthread_cond_wait cannot acquire it, thus the parent waits...

pthread_mutex_unlock(&m); // releases the mutex
// ok, the child released the mutex and the parent thread has been signaled.
// The mutex is available. pthread_cond_wait in the parent can
// acquire it and return.

父调用:

// now that the mutex is unlocked, the parent can return from its
// pthread_cond_wait(&c, &m) call from above, which returns with the mutex
// locked. A successful call to pthread_cond_wait(..) returns with the
// mutex locked, so this can't successfully return until it acquires the
// mutex.
pthread_mutex_unlock(&m);  // releases the locked mutex, no UB

当然,这只是几个操作顺序中的一个.我想你的误解是,pthread_cond_wait只有在获得互斥锁后才能成功返回.此时,它正确地在锁定的互斥锁上调用pthread_mutex_unlock(&m);.

C++相关问答推荐

try 使用sigqueue函数将指向 struct 体的指针数据传递到信号处理程序,使用siginfo_t struct 体从一个进程传递到另一个进程

如何在C宏中确定Windows主目录?

如何使用Python C API实现多线程程序?

GCC预处理宏和#杂注GCC展开

将整数的.csv文件解析为C语言中的二维数组

在没有动态内存分配的情况下,用C语言最快地将各种数组复制到单个较大的数组中

是否所有C编译器在将浮点数转换为整型数时都会隐式删除小数?

C lang:当我try 将3个或更多元素写入数组时,出现总线错误

将宏值传递给ARM链接器,该链接器将变量放置在特定位置

SSH会话出现意外状态

为什么函数是按照定义的顺序执行的,而不是按照从avr-c中的int main()调用的顺序执行的?

<;unistd.h>;和<;sys/unistd.h>;之间有什么区别?

如何仅使用软件重新初始化STM32微控制器中的USB枚举?

MacOS下C++的无阻塞键盘阅读

存储和访问指向 struct 的指针数组

Leet代码运行时错误:代码不会在Leet代码上编译,而是在其他编译器中编译,如netbeans和在线编译器

将char*铸造为空**

使用共享变量同步多线程 C 中的函数

C 预处理器中的标记分隔符列表

在 C 语言中,为什么 10/3 应该给出 3.333 却给出 3.000? (保存 10 和 3 的变量被声明为double)