c - 使用 pthread_mutex_t 锁传递给线程
问题描述
我正在学习 C 中的并发性。我知道有几种方法可以初始化 pthread_mutex_t。
这个简单的程序运行良好:
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void* worker(void* arg) {
pthread_mutex_lock(&lock);
printf("worker says hi\n");
pthread_mutex_unlock(&lock);
return NULL;
}
int main(int argc, char *argv[]) {
pthread_t p;
pthread_create(&p, NULL, worker, NULL);
pthread_mutex_lock(&lock);
printf("master says hi\n");
pthread_mutex_unlock(&lock);
pthread_join(p, NULL);
return 0;
}
但是,如果我不希望全局定义锁,我想我可以在我的主线程中定义它并将其传递给另一个线程,如下所示:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void* worker(void* arg) {
pthread_mutex_t lock = * (pthread_mutex_t *) arg;
pthread_mutex_lock(&lock);
printf("worker says hi\n");
pthread_mutex_unlock(&lock);
return NULL;
}
int main(int argc, char *argv[]) {
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_t p;
pthread_create(&p, NULL, worker, &lock);
pthread_mutex_lock(&lock);
printf("master says hi\n");
pthread_mutex_unlock(&lock);
pthread_join(p, NULL);
return 0;
}
但是,这不起作用。相反,它只打印 master says hi
和挂起。
我认为这可能是死锁,所以我在master中插入了一些睡眠时间,如下所示:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void* worker(void* arg) {
pthread_mutex_t lock = * (pthread_mutex_t *) arg;
pthread_mutex_lock(&lock);
printf("worker says hi\n");
pthread_mutex_unlock(&lock);
return NULL;
}
int main(int argc, char *argv[]) {
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_t p;
pthread_create(&p, NULL, worker, &lock);
sleep(1);
pthread_mutex_lock(&lock);
printf("master says hi\n");
pthread_mutex_unlock(&lock);
pthread_join(p, NULL);
return 0;
}
正如预期的那样,一秒钟后worker says hi
打印出来。master says hi
但是,如果我将睡眠移入工作人员,如下所示,它会再次挂起:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void* worker(void* arg) {
pthread_mutex_t lock = * (pthread_mutex_t *) arg;
sleep(1);
pthread_mutex_lock(&lock);
printf("worker says hi\n");
pthread_mutex_unlock(&lock);
return NULL;
}
int main(int argc, char *argv[]) {
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_t p;
pthread_create(&p, NULL, worker, &lock);
pthread_mutex_lock(&lock);
printf("master says hi\n");
pthread_mutex_unlock(&lock);
pthread_join(p, NULL);
return 0;
}
如果我将睡眠功能放在该行之上,pthread_mutex_t lock = * (pthread_mutex_t *) arg;
那么它就不会挂起。我不确定如何解释这种行为。
解决方案
我确实复制并粘贴了你所有的例子,没有一个被绞死或展示你的行为。
我不太确定,但我认为问题在于这里的线程函数:
pthread_mutex_t lock = * (pthread_mutex_t *) arg;
这会创建原始互斥锁的按位副本,并且根据结构的内容,这可能会导致您看到的问题。因此,glibc+pthreads 的不同实现/版本可能会产生不同的结果。
我总是将我的锁作为参数传递给线程,我没有问题,但是我没有创建我的锁的副本,所以我会尝试这个:
void* worker(void* arg) {
pthread_mutex_t *lock = arg;
pthread_mutex_lock(lock);
printf("worker says hi\n");
pthread_mutex_unlock(lock);
return NULL;
}
这应该可以解决您的问题。
推荐阅读
- arrays - Translate Array with Array
- selenium-webdriver - How to handle elements with type = "hidden" in Serenity BDD?
- python - Unable to query postgress sql from python
- ios - 如何在 Swift 中更改 UIView 中所有标签的颜色?
- azure-devops - azure pipeline TFVC check if a specific Build pipeline artifacts exist for a specific Branch name and specific tag
- android - 为什么 Retrofit 不向服务器发送 POST 请求?
- python - 有条件地移动饼图中单个数据标签的位置
- r - date index on R hourly data
- javascript - Mobile menu - CSS / DIV - Dim visible background around menu?
- neo4j - 从 Cypher (Neo4j) 中的 Id 列表中返回大子图