2017-10-03 5 views
0

Ich habe eine Funktion, die von thread1,2,3,4 ausgeführt wird .... Sobald thread1 Zugriff auf die Funktion erhält, verwende ich thread_cond für das Warten auf die anderen Threads. Sobald thread1 seine Arbeit erledigt, sende ich thread_signal an den gleichen cond. Thread2 führt die Funktion aus. Aber nachdem die Ausführung beendet ist, erhalten die anderen Threads keinen Zugriff auf die Funktion.Wie kann man sicherstellen, dass die Threads 2,3 und 4 auf das gleiche Signal von Thread1 warten?

Bitte helfen Sie mir

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

int limit = 0; 
pthread_mutex_t mutex[100]; 
pthread_cond_t cond[100]; 
pthread_t tid[100]; 

void *enter() 
{ 
    if (limit == 1) 
    { 
     printf("waiting\n"); 
     pthread_cond_wait(&cond[1],&mutex[1]); 
    } 
    gotofunction(); 
} 

void gotofunction() 
{ 
    limit++; 
    /* Do work */ 
    printf("Doing work\n"); 
    sleep(1); 
    limit--; 
    printf("Going to give signal\n"); 
    pthread_cond_signal(&cond[1]); 
} 

int main() 
{ 
    int n,i; 
    scanf("%d",&n); 
    for (i=0;i<100;i++) 
    { 
     pthread_mutex_init(&mutex[i], NULL); 
     pthread_cond_init(&cond[i], NULL); 
    } 
    for (i=0;i<n;i++) 
    { 
     pthread_create(&tid[i], NULL, enter, NULL); 
     sleep(0.5); 
    } 
    for (i=1;i<=n;i++) 
    { 
     pthread_join(tid[i], NULL); 
    } 
} 

Grundsätzlich thread1 prints "tun Arbeit" Thread2 prints "Arbeit erledigt" Dann nichts für die anderen Threads geschieht

+0

Das 'pthread_cond_signal' signalisiert nur * einen * (zufälligen) Thread. Wenn Sie die Handbuchseite für z.B. 'Pthread_cond_signal', es sagt Ihnen nichts über eine andere Funktion? Vielleicht ein [* broadcast *] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_broadcast.html) das Signal? –

+0

@Someprogrammerdude Ich glaube Broadcast weckt alle Threads auf. Ich möchte nur einen der thread aufwecken und seine arbeit dann wecken einen weiteren thread usw. – user7693981

+1

Dann vielleicht eine * kette * von 'pthread_cond_signal'? Sobald ein Thread nach einem Signal aufwacht, ruft er wiederum 'pthread_cond_signal' auf. –

Antwort

0

Sie den Mutex haben müssen, die Sie pthread_cond_wait() weitergegeben gesperrt zu dem Zeitpunkt, an dem Sie es anrufen. Dieser Mutex muss auch gesperrt sein, während Sie die Bedingung überprüfen und ändern, mit der die Bedingungsvariable gepaart ist (in diesem Fall ist limit == 1 diese Bedingung).

Sie sollten auch das Muster while (condition) { pthread_cond_wait() } (statt if (condition)) verwenden, da die Bedingungsvariable möglicherweise aufwacht, ohne dass die Bedingung tatsächlich erfüllt ist.

Ändern Sie den Code den Mutex um die Zugriffe auf limit zu sperren und die Sperre aufheben, während der Arbeit zu simulieren, sieht wie folgt aus:

void *enter() 
{ 
    pthread_mutex_lock(&mutex[1]); 
    while (limit == 1) 
    { 
     printf("waiting\n"); 
     pthread_cond_wait(&cond[1],&mutex[1]); 
    } 
    gotofunction(); 
    pthread_mutex_unlock(&mutex[1]); 
    return NULL; 
} 

void gotofunction() 
{ 
    limit++; 
    pthread_mutex_unlock(&mutex[1]); 

    /* Do work */ 
    printf("Doing work\n"); 
    sleep(1); 

    pthread_mutex_lock(&mutex[1]); 
    limit--; 
    printf("Going to give signal\n"); 
    pthread_cond_signal(&cond[1]); 
} 

Natürlich, wenn Sie eine Grenze von 1 überprüfen gegen, sie konnte es einfach Verwenden Sie stattdessen einen einfachen Mutex - aber dieses Schema könnte erweitert werden, damit N-Threads gleichzeitig arbeiten können, indem Sie die Bedingung in while (limit >= N) ändern.

Verwandte Themen