Pthread同步——打印偶数奇数

Pthread synchronization - print even odd numbers

我是 pthreads 的新手。我正在尝试从两个线程打印偶数和奇数。下面的代码有什么问题?它的目的是创建两个线程——一个打印奇数,另一个打印偶数。数字必须按顺序打印。好像卡住了(ideone exceeded time limit)。。我盯着看了好久。只是想不通哪里出了问题..

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

您的程序存在多个问题-

  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) 循环并再次返回睡眠状态。这一次,没有人可以唤醒可怜的灵魂。正是因为这个原因,你需要在while循环
  2. 中测试终止条件n>=max

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

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