Pthread同步-打印偶数

时间:2018-08-22 21:59:05

标签: c multithreading pthreads mutex

我是pthread的新手。我正在尝试从两个线程打印偶数和奇数。下面的代码有什么问题?它的目的是创建两个线程-一个将打印奇数,另一个将打印偶数。数字必须按顺序打印。好像卡住了(ideone中超过了时间限制)..我已经花了很多时间盯着它。只是不知道出什么问题了。.

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


pthread_mutex_t lock;
int n = 0;
int max = 10;

pthread_cond_t even;
pthread_cond_t odd;


void* print_odd(void *x)
{
    while(1)
    {
        pthread_mutex_lock(&lock);
        while(n%2 != 0)
        {
            pthread_cond_wait(&even, &lock);
        }
        if(n >= max)
        {
            pthread_mutex_unlock(&lock);
            pthread_exit(NULL);
        }
        printf("Thread A : %d", ++n);
        pthread_cond_signal(&odd);
        pthread_mutex_unlock(&lock);
    }
}


void* print_even(void *x)
{
    while(1)
    {
        pthread_mutex_lock(&lock);
        while(n%2 == 0)
        {
            pthread_cond_wait(&odd, &lock);
        }
        if(n >= max)
        {
            pthread_mutex_unlock(&lock);
            pthread_exit(NULL);
        }
        printf("Thread B : %d", ++n);
        pthread_cond_signal(&even);
        pthread_mutex_unlock(&lock);
    }
}

main()
{
    pthread_t t1, t2;
    pthread_create(&t1, NULL, print_odd, NULL);
    pthread_create(&t2, NULL, print_even, NULL);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    exit(0);
}

2 个答案:

答案 0 :(得分:4)

您的程序存在多个问题-

  1. 如注释中所建议,lock和条件变量需要初始化。
pthread_mutex_t lock = PTHREAD_LOCK_INITIALIZER;
pthread_cond_t  even = PTHREAD_COND_INITIALIZER;
pthread_cond_t  odd =  PTHREAD_COND_INITIALIZER;

即使您没有将它们初始化为全局变量,也可能在这里意外地幸运,因为它们已被初始化为零,并且正确地初始化它们时,pthread实现实际上可能是初始化为零。

  1. 您的printf没有\n,因此输出不会刷新到屏幕。只需添加换行符,您就会看到线程确实正在运行。

  2. n达到10时,即print_odd线程从9开始递增时,它简单地退出而没有发信号通知偶数线程。因此,您的偶数线程挂在cond_wait中,而您的main线程挂在pthread_join中。您可以通过退出偶数线程之前发信号通知偶数线程来解决此问题。

编辑,我发现了另一个问题

  1. 即使奇数线程在退出之前就向偶数线程发出信号,从n=10开始,偶数线程也不会退出while(n%2 == 0)循环并再次进入睡眠状态。这次,没有人唤醒可怜的灵魂。因此,您需要测试n>=max循环内的终止条件while

答案 1 :(得分:-3)

pthread_cond_wait 正在阻塞调用线程。在您的情况下,您已要求线程等待 true 奇数和偶数条件。相反,他们应该等待不正确条件。

  • 虽然 i%2 == 0奇数 线程应该调用例程内部的等待函数。
  • 虽然i!=2偶数线程应该调用等待函数。