2016-04-20 12 views
0

Ich habe eine Klasse Threadpool erstellt und leer Funktion execute_thread_helper() genannt, die innerhalb void* execute_thread(void* arg) (seine Funktion gegeben hat auf das Thema auf diese Weise: ret = pthread_create(&workers[i], NULL, execute_thread, (void*)this);) genannt wirdpthread_cond_wait und pthread_mutex_lock funktioniert nicht wie erwartet

void ThreadPool::execute_thread_helper() 
{ 
    Task task; 

    pthread_mutex_lock(&mutex); 

    while(TaskList.empty()) // Previously "if" 
    { 
     cout << "Thread #" << pthread_self() << " is blocked. "<< endl; 
     pthread_cond_wait(&conditionVar, &mutex); 
    } 

    task = TaskList.front(); 
    TaskList.pop(); 

    cout << "Thread #" << pthread_self() << " going to run the function. "<< endl; 

    threadFunction(task); 

    pthread_mutex_unlock(&mutex); 
} 

Aufgaben sind auf diese Weise zu einer Warteschlange von Aufgaben hinzugefügt -

void ThreadPool::add_task(Task newTask) 
{  
    pthread_mutex_lock(&mutex); 

    TaskList.push(newTask);  
    pthread_cond_signal(&conditionVar); 

    pthread_mutex_unlock(&mutex); 

} 

Soweit ich verstehe, sobald ein Thread erstellt werden - es wird versuchen execute_thread zu laufen. Und dann, bei einer leeren Warteschlange, erwarte ich pthread_cond_wait "put" den Thread in den Ruhezustand (und tun Sie es mit allen erstellten Threads), bis es durch pthread_cond_signal in add_task aufwachen wird.

Well..i versucht, das Programm auf einem einzigen Thread Prüfung und bekam dieses Ergebnis (i add_task havent gerade versucht, den Pool zu erstellen.) -

Thread #139859560904448 is blocked. 
Thread #139859560904448 going to run the function. 
in map() key is and value is 0 

Ich verstehe nicht, wie der Thread übergeben die if-Anweisung, wenn sie zuvor in der Warteschleife war.

Ausgang auf den Versuch 3 Thread-Pool zu erstellen -

Thread #140013458028288 is blocked. 
Thread #140013458028288 going to run the function. 
in map() key is and value is 0 
Thread #140013458028288 going to run the function. 
in map() key is and value is 0 
Thread #140013458028288 going to run the function. 
in map() key is and value is 0 

Warum nicht die anderen 2 Fäden auf Eis gelegt?

EDIT

Dank Sergeya, tat das, wenn mit Weile Schalt Hilfe. Aber dennoch versuchen 3-Thread-Pool, führt dies zu machen -

Thread #139916558706432 is blocked. 
Thread #139916558706432 is blocked. 
Thread #139916558706432 is blocked. 
Thread #139916558706432 is blocked. 
Thread #139916558706432 is blocked. 
Thread #139916558706432 is blocked. 
Thread #139916558706432 is blocked. 
Thread #139916558706432 is blocked. 

Warum keine anderen Threads erstellt werden? sollen sie nicht alle gleichzeitig erstellt werden und abwechselnd drucken, dass sie blockiert sind?

+0

'pthread_mutex_lock (& ​​mutex); // mutex lock' - warum nicht 'pthread_mutex_lock (& ​​mutex); // pthread_mutex_lock'? Würde der Code in der letzteren Form viel klarer machen, nicht wahr? – SergeyA

Antwort

2

Zustandsvariablen sind anfällig für sogenannte * spurios Wake-ups. Es bedeutet, dass der Code entsperrt ist, aber der Zustand hat sich nicht wirklich geändert und es wurde nicht signalisiert.

Deshalb müssen Sie immer die wait Funktion in einer Schleife aufrufen und den Zustand nach jedem Wecken überprüfen.

0

pthread_cond_signal(&conditionVar); wird nur ein der wartenden Threads aufwachen. Wenn Ihre Aufgaben kurz genug sind, werden Sie immer wieder den gleichen Thread aufwecken. Es gibt keine Fairness. :-)

Sie können alle wartenden Threads auch aufwecken, indem Sie pthread_cond_broadcast(&conditionVar); verwenden. Dann sollten Sie sehen, dass alle Ihre Threads immer wieder aufgeweckt werden. Aber für Ihren Thread-Pool sollte es nicht notwendig sein, die Broadcast-Variante zu verwenden.

Verwandte Themen