Я занимаюсь синхронизацией pthread с использованием мьютексов и условных переменных. В приведенном ниже коде я создаю 3 потока, и я ожидаю, что выходные данные будут сообщать о том, какой поток выполнен, а затем выходить из основного потока, сообщая значение счетчика. Однако я заметил, что у меня может быть 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)
Я не знаю причину этих выводов. Пожалуйста, помогите мне. Кстати, этот код не зависит от структуры списка ссылок.
------ EDIT -----
После некоторых исследований я выполнил код, как и ожидал, благодаря владельцу этой ссылки 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;