2017-12-20 20 views
0

Ich möchte ein Programm schreiben, die alle anderen Pthreads ohne Hauptthread stoppen kann (ich auflegen) pthread_kill, um ein Signal an den Ziel-Thread zu senden, um seine Signal-Handler, die blockieren kann, zu rufen selbst. Aber ich bin stecken geblieben. Hier ist der Code unten: (Dies gilt)Pthread mit pthread_cond_wait innerhalb Signalhandle blockiert

#include <iostream> 
#include <signal.h> 
#include <pthread.h> 
#include <unistd.h> 
#include <cassert> 

using namespace std; 

pthread_mutex_t _mutex; 
pthread_cond_t cond; 

void cur_thread_wait(int sig) 
{ 
    cout << pthread_self() << endl; 

// pthread_mutex_lock(&_mutex); 
    pthread_cond_wait(&cond, &_mutex); 
// pthread_mutex_unlock(&_mutex); 
} 

void signal_all() 
{ 
    pthread_cond_broadcast(&cond); 
} 

void *print(void *) 
{ 
    pthread_detach(pthread_self()); 
    for (int i = 0; i < 100; i ++) { 
     cout << dec << i << endl; 
    } 
    return nullptr; 
} 


int main(int argc, char *argv[]) 
{ 
    pthread_mutex_init(&_mutex, nullptr); 
    pthread_cond_init(&cond, nullptr); 

    signal(SIGUSR1, cur_thread_wait); 

    pthread_t pid1, pid2, pid3; 
    pthread_create(&pid1, nullptr, print, nullptr); 
    pthread_create(&pid2, nullptr, print, nullptr); 
    pthread_create(&pid3, nullptr, print, nullptr); 

// usleep(400); 

    pthread_kill(pid1, SIGUSR1); 
    pthread_kill(pid2, SIGUSR1); 
    pthread_kill(pid3, SIGUSR1); 

    signal_all(); 


    pthread_exit(nullptr); 
} 

In der Tat, ich glaube, es gibt wirklich keine Notwendigkeit zu erstellen mutex ... Ich bin ein Neuling auf Linux-Programmierung. Wie kann ich dieses Problem beheben? Vielen Dank.

+0

Dies ist kaputt - Sie sollten niemals in einem Signal-Handler blockieren! –

Antwort

1

Sie tun müssen den Mutex vor dem Aufruf pthread_cond_wait sperren; Es erwartet, dass es gesperrt wird, es entsperrt es, wartet auf die Bedingung, die geltend gemacht werden soll, und schließt es dann wieder, bevor es zu Ihnen zurückkehrt.

Von pthread_cond_wait(3p):

int pthread_cond_wait(pthread_cond_t *restrict cond, 
    pthread_mutex_t *restrict mutex); 

Die pthread_cond_timedwait() und pthread_cond_wait() Funktionen auf einer Zustandsgröße blockieren soll. Die Anwendung muss sicherstellen, dass diese Funktionen mit Mutex vom aufrufenden Thread gesperrt aufgerufen werden; Andernfalls tritt ein Fehler (für PTHREAD_MUTEX_ERRORCHECK und robuste Mutexe) oder undefiniertes Verhalten (für andere Mutexe) auf.

+0

Danke. Ich finde meine Schuld ... wenn ich 'usleep' kurz vor' signal_all' setze, geht das Programm nach rechts. Außerdem hast du Recht weil 'mutex' notwendig ist. – wind2412

+0

Danke für das Update! Sie können auch 'sched_yield' auf den meisten Systemen (einschließlich Linux) verwenden. –

+0

Er sollte in einem Signalhandler keine blockierenden Aufrufe machen. Da die Frage mit C++ markiert ist, kann das Löschen und Löschen von Posix-Threads in C++ zu Problemen führen. Siehe z.B. https://skaark.wordpress.com/2010/08/26/pthread_cancel-condensed-harmful/ –

Verwandte Themen