C语言 线程同步 - 打印偶数奇数



我是pthreads的新手。我正在尝试从两个线程打印偶数和奇数。下面的代码有什么问题?它的目的是创建两个线程 - 一个将打印奇数,另一个将打印偶数。数字必须按顺序打印。它似乎卡住了(在 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);
}

您的程序存在多个问题-

  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_waitmain线挂在pthread_join.您可以通过在退出奇数线程之前发出信号来唤醒偶数线程来解决此问题。

编辑我发现了另一个问题

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

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

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

最新更新