2016-10-28 26 views
0

ich zur Zeit als zu verwirrt bin, warum der folgende Code die folgenden nicht gedruckt wird: nurVerständnis Pthread

My value is 0 
My value is 1 
My value is 2 

Jedes Mal, wenn ich dieses Ich laufe entweder bekommen 1-2 gedruckten Linien oder nichts, und das Programm setzt sich ihr bis ich ctrl-c. Ich habe das Gefühl, dass es etwas mit mir zu tun haben könnte, wenn ich die gleiche Zustandsvariable und Mutex mit 3 verschiedenen Threads verwende, wäre das korrekt? Alle Erklärungen werden sehr geschätzt.

#include <stdio.h> 
#include <pthread.h> 
#include <assert.h> 
#include <unistd.h> 
#include <stdlib.h> 

struct id_holder 
{ 
int id; 
}; 

pthread_mutex_t intersectionMutex = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t directionCondition = PTHREAD_COND_INITIALIZER; 
struct id_holder * holder; 

void * logic(void* val) 
{ 
    struct id_holder * id_struct = (struct id_holder *) val; 

    pthread_cond_wait(&directionCondition, &intersectionMutex); 
    printf("My value is %d\n", id_struct->id); 
    free(id_struct); 
    return NULL; 
} 

int main(void) 
{ 
    pthread_t threads[3]; 

    for(int i = 0; i <3; i++) 
    { 
     holder = (struct id_holder *) malloc(sizeof(struct id_holder)); 
     holder->id = i; 
     pthread_create(&threads[i], NULL, logic, holder); 
    } 

    for(int i = 0; i < 3; i++) 
    { 
     sleep(1); 
     pthread_cond_signal(&directionCondition); 
    } 

    for(int i = 0; i < 3; i++) 
    { 
     pthread_join(threads[i], NULL); 
    } 

    return 0; 
} 

Antwort

3

Wenn Bedingung für oder signalisiert gewartet wird, muss sie unter dem Schloss durchgeführt werden, da sonst das Verhalten, wie es könnte in Race-Bedingung ist unberechenbar. Daher sollten Sie den Code wie folgt aussehen:

pthread_mutex_lock(&intersectionMutex); 
pthread_cond_wait(&directionCondition, &intersectionMutex); 
pthread_mutex_unlock(&intersectionMutex); 

Und das gleiche gilt für main (Sie die Sperre außerhalb der Schleife bewegen können, wenn Sie möchten):

for(int i = 0; i < 3; i++) { 
    sleep(1); 
    pthread_mutex_lock(&intersectionMutex); 
    pthread_cond_signal(&directionCondition); 
    pthread_mutex_unlock(&intersectionMutex); 
} 

Noch ist der Code nicht zu 100% sicher, da die Hauptthread kann die Bedingung signalisieren, bevor der untergeordnete Thread die Wartezeit aufruft. Obwohl es hier aufgrund der sleep() in der Hauptfunktion sehr unwahrscheinlich ist, sollte es im Allgemeinen eine Variable geben, die angibt, ob die Wartezeit tatsächlich benötigt wird oder nicht. Mit anderen Worten, Bedingungen sind keine Warteschlange, können aber zum Erstellen einer Warteschlange verwendet werden.