2012-10-22 9 views
5

Hallo, Ich bin neu in Multi-Thread-Programmierung. Ich versuche einen Code zu erstellen, der einen Thread THREAD1 erstellt, der, nachdem er etwas getan hat, zwei andere Threads auslöst, sagen THREAD2 und THREAD3, und beendet dann.Pthreads: ein Thread, der andere Threads auslöst

Ich schrieb zwei mögliche Lösungen.

1) Die Verwendung von Bedingungsvariablen (nicht funktioniert: in einigen Fällen ich eine Sackgasse erhalten):

pthread_mutex_t ready_mutex = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER; 
bool ready = false; 

void* trigger(void*); 
void* func1(void*); 
void* func2(void*); 

int main() 
{ 
    pthread_t thread1; 
    pthread_t thread2; 
    pthread_t thread3; 
    pthread_create(&thread1, 0, &trigger, 0); 
    pthread_create(&thread2, 0, &func1, 0); 
    pthread_create(&thread3, 0, &func2, 0); 
    pthread_join(thread1, 0); 
    pthread_join(thread2, 0); 
    pthread_join(thread3, 0); 
} 

void *trigger(void*) 
{ 
    pthread_mutex_lock(&ready_mutex); 
    ready = true; 
    pthread_cond_broadcast(&ready_cond); 
    pthread_mutex_unlock(&ready_mutex); 
    return 0; 
} 

void *func1(void*) 
{ 
    while (!ready) // Needed to avoid spuriuos wake-up 
    { 
     pthread_mutex_lock(&ready_mutex); 
     pthread_cond_wait(&ready_cond, &ready_mutex); 
     pthread_mutex_unlock(&ready_mutex); 
    } 
    std::cout << "In 'func1'>> Do something" << std::endl; 
    return 0; 
} 

void *func2(void*) 
{ 
    while (!ready) // Needed to avoid spuriuos wake-up 
    { 
     pthread_mutex_lock(&ready_mutex); 
     pthread_cond_wait(&ready_cond, &ready_mutex); 
     pthread_mutex_unlock(&ready_mutex); 
    } 
    std::cout << "In 'func2'>> Do something" << std::endl; 
    return 0; 
} 

2) Thread1 erzeugt direkt die beiden anderen Threads.

pthread_mutex_t ready_mutex = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER; 

pthread_t thread1; 
pthread_t thread2; 
pthread_t thread3; 

void* trigger(void*); 
void* func1(void*); 
void* func2(void*); 

int main() 
{ 
    pthread_create(&thread1, 0, &trigger, 0); 

    pthread_join(thread1, 0); 
    pthread_join(thread2, 0); 
    pthread_join(thread3, 0); 
} 

void *trigger(void*) 
{ 
    std::cout << "In 'trigger'>> Do something" << std::endl; 

    pthread_create(&thread2, 0, &func1, 0); 
    pthread_create(&thread3, 0, &func2, 0); 

    return 0; 
} 

void *func1(void*) 
{ 
    std::cout << "In 'func1'>> Do something" << std::endl; 

    return 0; 
} 

void *func2(void*) 
{ 
    std::cout << "In 'func2'>> Do something" << std::endl; 

    return 0; 
} 

Ich möchte Ihre Meinung wissen. Vielen Dank

+0

Ihre zweite Implementierung scheint gut zu funktionieren, was ist Ihrer Meinung nach falsch? – engineerC

+0

Ihre zweite Option ist sauberer und netter. Ich würde das tun. –

+0

@CaptainMurphy: Ich frage mich nur, ob es einen besseren Weg gibt, dieses Ziel zu erreichen. Aus POSIX-Handbuchseiten scheint mir, dass Zustandsvariablen für dieses Ziel besser geeignet sind, da sie verwendet werden können, um für ein bestimmtes Ereignis zu signalisieren. –

Antwort

5

Verwendung von Bedingungsvariablen (nicht funktioniert: in einigen Fällen ich eine Sackgasse erhalten):

Der Code den Mutex nicht sperren, wenn der Zustand der gemeinsamen Kontrolle Variable ready. Wenn es den Mutex ready gesperrt hat, kann sich das zu diesem Zeitpunkt gut geändert haben, deshalb sehen Sie Deadlocks.

Die richtige Version für Zustandsänderung mit einer Zustandsgröße warten ist (Fehler ausgelassen Prüfung):

pthread_mutex_lock(&ready_mutex); 
while(!ready) // Needed to avoid spuriuos wake-up 
    pthread_cond_wait(&ready_cond, &ready_mutex); 
// ready == true here 
pthread_mutex_unlock(&ready_mutex); 

Die oben geht davon aus, dass ready immer nur dann geändert, wenn der gleiche Mutex gehalten wird.

+0

Ja, du hast Recht. Wenn ich also zu meiner Frage zurückkomme, sollte ich Condition-Variablen (Lösung # 1) oder verzögerte Thread-Erstellung (Lösung # 2) verwenden? –

+1

@ seg.fault Ich würde [Ockhams Rasiermesser] (http://en.wikipedia.org/wiki/Occam's_razor) verwenden: mehrere Lösungen für ein Problem wählen, wählen Sie einfacher. –

Verwandte Themen