我对C语言中的系统编程非常陌生,我使用pthreads创建两个线程,增加计数器并显示值。如果计数器值为偶数,则线程1递增,如果计数器值为奇数,则线程2递增。
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition_var = PTHREAD_COND_INITIALIZER;
void *functionCount1();
void *functionCount2();
int count = 0;
#define COUNT_DONE 2
int main()
{
pthread_t thread1, thread2;
pthread_create( &thread1, NULL, &functionCount1, NULL);
pthread_create( &thread2, NULL, &functionCount2, NULL);
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
printf("Final count: %d\n",count);
exit(0);
}
void *functionCount1()
{
for(;;)
{
pthread_mutex_lock( &count_mutex );
pthread_cond_wait( &condition_var, &count_mutex );
count++;
printf("Counter value functionEven: %d\n",count);
pthread_mutex_unlock( &count_mutex );
if(count >= COUNT_DONE) {
printf("Thread 1: Exit condition reached.\n");
return(NULL);
}
}
}
void *functionCount2()
{
for(;;)
{
pthread_mutex_lock( &count_mutex );
if( count % 2 == 0)
{
pthread_cond_signal( &condition_var );
}
else
{
count++;
printf("Counter value functionOdd: %d.\n",count);
}
pthread_mutex_unlock( &count_mutex );
if(count >= COUNT_DONE) {
printf("Thread 2: Exit condition reached.\n");
return(NULL);
}
}
}
从我可以观察到的问题是,线程2首先到达它的存在状态并且它使线程1挂起。
Counter value functionEven: 1
Counter value functionOdd: 2.
Thread 2: Exit condition reached.
(This is where it hangs, I have to press Ctrl-C to end)^C
当线程2到达其退出状态时,我尝试了另一个锁,只有当线程1存在条件被调用时才解锁它。但这似乎没有做任何事情。
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
if(count >= COUNT_DONE) {
printf("Thread 1: Exit condition reached.\n");
pthread_mutex_unlock( &mutex2 );
return(NULL);
}
if(count >= COUNT_DONE) {
pthread_mutex_lock( &mutex2 );
printf("Thread 2: Exit condition reached.\n");
return(NULL);
}
适当计数的最终解决方案。
下面的答案帮助了很多,它解决了主要问题。
pthread_cond_wait( &condition_var, &count_mutex );
if(count >= COUNT_DONE) {
return(NULL);
}
count++;
printf("Counter value functionEven: %d\n",count);
答案 0 :(得分:0)
在退出functionCount2之前,您必须按如下方式发出条件变量的信号;
if(count >= COUNT_DONE) {
printf("Thread 2: Exit condition reached.\n");
pthread_cond_signal( &condition_var );
return(NULL);
}