我是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);
}
您的程序存在多个问题-
- 如注释中所建议的,需要初始化
lock
和条件变量。
pthread_mutex_t lock = PTHREAD_LOCK_INITIALIZER; pthread_cond_t even = PTHREAD_COND_INITIALIZER; pthread_cond_t odd = PTHREAD_COND_INITIALIZER;
即使没有初始化,您也可能在这里意外地走运,因为您已经将它们声明为全局,并且它们将是零启动的,并且当您正确初始化它们时,pthread实现实际上可能是零启动的。
您的
printf
没有n
,因此输出不会刷新到屏幕。只需添加换行符,您就会看到您的线程确实正在运行。当
n
达到 10 时,即当print_odd
线程从9
递增时,它只是退出而不发出偶数线程的信号。因此,您的偶数线挂在cond_wait
,main
线挂在pthread_join
.您可以通过在退出奇数线程之前发出信号来唤醒偶数线程来解决此问题。
编辑我发现了另一个问题
- 即使奇数线程在退出
- 之前向偶数线程发出信号,因为
n=10
,偶数线程也不会退出while(n%2 == 0)
循环并再次进入睡眠状态。这一次,没有人能唤醒可怜的灵魂。正是出于这个原因,您需要在while
循环内测试n>=max
终止条件
pthread_cond_wait
阻塞了调用线程。在您的情况下,您要求线程等待奇数和偶数的真实条件。相反,他们应该等待不正确的条件。
i%2 == 0
时,奇数线程应该调用例程内部的等待函数。i!=2
时,偶数线程应该调用等待函数。