互斥锁挂起或不起作用

时间:2016-02-09 19:00:10

标签: c locking pthreads mutex

我使用pthreads在父进程旁边创建子进程。我尝试使用互斥锁在子进程中的第一个print语句之后停止,并在父进程中的第二个print语句之后继续:

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

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

void *print(void *attr)
{
printf("I am the child process\n");
pthread_mutex_lock(&lock);
pthread_cond_wait(&cond, &lock);
printf("The child process is done\n");
pthread_mutex_unlock(&lock);
return 0;
}

int main()
{

pthread_t child;
pthread_mutex_lock(&lock);
printf("I am the parent process\n");
pthread_create(&child, NULL, print, NULL);
pthread_join(child, NULL);
printf("The parent process is done\n");
pthread_mutex_unlock(&lock);
pthread_cond_signal(&cond);
return 0;
}

原始输出如下:

I am the parent process
I am the child process
The child process is done
The parent process is done

我正在寻找的输出如下:

I am the parent process
I am the child process
The parent process is done
The child process is done

我不能为我的生活找出如何用互斥量实现这一目标,我最接近的是它在无限期悬挂之前达到前两个陈述。我也有原始输出,好像互斥锁语句什么也没做。

有人能帮我解决这个问题吗?提前谢谢。

1 个答案:

答案 0 :(得分:2)

您只需要在父线程和子线程之间发出更好的信号。这应该这样做:

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

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  cond = PTHREAD_COND_INITIALIZER;
int             child_done = 0;
int             parent_done = 0;

void *print(void *attr)
{
    printf("I am the child process\n");
    pthread_mutex_lock(&lock);
    child_done = 1;
    pthread_cond_broadcast(&cond); // Because this thread also waits
    while (!parent_done)
        pthread_cond_wait(&cond, &lock);
    printf("The child process is done\n");
    pthread_mutex_unlock(&lock);
    return 0;
}

int main()
{
    pthread_t child;
    pthread_mutex_lock(&lock);
    printf("I am the parent process\n");
    pthread_create(&child, NULL, print, NULL);
    while (!child_done)
        pthread_cond_wait(&cond, &lock);
    printf("The parent process is done\n");
    parent_done = 1;
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&lock);
    pthread_join(child, NULL);
    return 0;
}