Синхронизация Pthread с условными переменными

user3713335 спросил: 07 октября 2018 в 11:18 в: c

Я занимаюсь синхронизацией 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;

0 ответов