首页 > 解决方案 > 使用 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;那么它就不会挂起。我不确定如何解释这种行为。

标签: cmultithreading

解决方案


我确实复制并粘贴了你所有的例子,没有一个被绞死或展示你的行为。

我不太确定,但我认为问题在于这里的线程函数:

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;
}

这应该可以解决您的问题。


推荐阅读