我正在通过使用互斥对象和条件变量来练习有关pthread同步。在下面的代码中,我创建了3个线程,并且期望看到输出告诉执行了哪个线程,然后从主线程退出,报告了count的值。但是,我观察到可以有3种不同的输出。 这是我的代码:
#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
typedef struct node{
int data;
struct node* next;
}LinkList;
LinkList *list = NULL ;
//LinkList *head;
int count;
int enter;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void* trythis(void *arg)
{
pthread_mutex_lock(&lock);
//enter = 0;
printf("Thread sleeps... \n");
while(!enter){
pthread_cond_wait(&cond,&lock);
}
enter = 1;
printf("Thread %d Enter = %d\n",count++,enter);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);
return NULL;
}
int main(int argc, char** argv){
pthread_t tid[3];
int error;
int i = 0;
printf("Main Beginning1\n");
int p = pthread_mutex_init(&lock,NULL);
if(p != 0){
printf("Mutex failed \n");
exit(1);
}
printf("Main Beginning2\n");
while(i < 3)
{
error = pthread_create(&(tid[i]), NULL, &trythis, NULL);
if (error != 0)
printf("\nThread can't be created : [%s]", strerror(error));
i++;
}
printf("Main Beginning3\n");
/*for(int i = 0; i < 3; i++){
pthread_join(tid[i], NULL);
}*/
printf("Main Beginning4\n");
pthread_mutex_lock(&lock);
enter = 1;
printf("Main Beginning\n");
while(count < 2){
pthread_cond_wait(&cond,&lock);
printf("count : %d\n",count);
}
pthread_cond_signal(&cond);
printf("Main count = %d\n",count);
pthread_mutex_unlock(&lock);
pthread_mutex_destroy(&lock);
return 0;
}
我的输出是:
***FIRST OUTPUT***
oguzliv@oguzliv-VirtualBox:~/Desktop/OSindAir$ ./linklist
Main Beginning1
Main Beginning2
Thread sleeps...
Main Beginning3
Thread sleeps...
Main Beginning4
Main Beginning
Thread sleeps...
Thread 0 Enter = 1
Thread 1 Enter = 1
Thread 2 Enter = 1
count : 3
Main count = 3
***SECOND OUTPUT***
oguzliv@oguzliv-VirtualBox:~/Desktop/OSindAir$ ./linklist
Main Beginning1
Main Beginning2
Thread sleeps...
Main Beginning3
Main Beginning4
Main Beginning
Thread sleeps...
Thread 0 Enter = 1
Thread sleeps...
Thread 1 Enter = 1
count : 2
Main count = 2
***THIRD OUTPUT***
oguzliv@oguzliv-VirtualBox:~/Desktop/OSindAir$ ./linklist
Main Beginning1
Main Beginning2
Thread sleeps...
Thread sleeps...
Main Beginning3
Main Beginning4
Thread sleeps...
Main Beginning
(waits infinitely)
我不知道这些输出的原因。请帮我。顺便说一句,此代码独立于链接列表结构。
------编辑-----
经过一番研究,感谢此链接https://gist.github.com/rtv/4989304
的所有者,我按预期执行了代码但是,我仍然对以前的代码感到困惑,为什么它不能作为已编辑的代码执行。所有更改为:
while(!enter){
pthread_cond_wait(&cond,&lock);
}
enter = 1;
printf("Thread %d Enter = %d\n",count++,enter);
pthread_cond_signal(&cond);
到
const int myid = long(args);
printf("Thread sleeps with ID : %d\n",myid);
pthread_mutex_lock(&lock);
count++;
printf("Thread ID : %d count : %d",myid,count);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);
return NULL;
答案 0 :(得分:0)
从根本上讲,您的原始代码正在为enter的价值而战。请考虑以下两种情况:
现实世界可以是这些的任意混合,因此您可能会发现留下0..3线程和/或main阻塞了。我认为答案是您的主行:
pthread_mutex_lock(&lock);
enter = 1;
应该添加:
pthread_cond_signal(&cond);
这样,已经在等待输入的任何人都将被释放。 从流程的角度来看; “ trythis”正在消耗输入,并产生计数; “主要”是生产输入和消耗计数。