2012-04-15 8 views
0

Ich habe ein relativ einfaches Pthread-Programm unter Linux. Zu diesem Zweck habe ich es zu einem kleinen Stück ausgezogen, am Ende veröffentlicht.wait() blockiert nicht, in Linux und Pthreads

Alle man-Seiten für wait (2) sagen, dass wait() blockiert wird, wenn WNOHANG nicht verwendet wird (was nicht einmal für wait() spezifiziert werden kann). Mit Blick auf Truss-Ausgang, es ist nur eine Non-Stop-Wiederholung:

5460 wait4(-1, 0x7f8ee479fea8, 0, NULL) = -1 ECHILD (No child processes) 

wieder auf Manpage von wait4 suchen (2), heißt es, dass die Rückkehr Ergebnisse gleich sind wie für waitpid() und waitpid sollte Block, es sei denn es WNOHANG ist, und Truss zeigt, dass der Anruf mit Optionen 0.

Als Referenz wird hergestellt wurde, ist dies:

  • 2.6.32-300.3.1.el6uek.x86_64
  • glibc -2.12-1.47.el6_2.9.x86_64
  • gcc-4.4.6-3.el6.x86_64
  • kompiliert mit gcc -pthread -lpthread -o PTW -Wall ptw.c

-

#include <pthread.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/wait.h> 



static pthread_mutex_t _lock = PTHREAD_MUTEX_INITIALIZER; 
static pthread_cond_t _sem = PTHREAD_COND_INITIALIZER; 

static void* waiter(void*); 

int main(int argc, char ** argv) { 

    pthread_t thr; 

    if (pthread_create(&thr, 0, waiter, 0)) { 
     perror("pthread_create"); 
     return 1; 
    } 

    pthread_mutex_lock(&_lock); 
    pthread_cond_wait(&_sem, &_lock); 

    return 0; 

} 

void* waiter(void* arg) { 

    while (1) { 
     int status; 
     int p = wait(&status); 
     if (p<0) { 
      perror("wait"); 
      // fprintf(stderr, "wait returned without exited child\n"); 
     } 
    } 

    return 0; 

} 

Antwort

1

wait() wird auch sofort zurück, wenn kein Kind-Prozess für mit dem Wert zu warten ist -1 und errno Satz zu ECHILD (das ist, was Ihr strace Sie zeigt). Was haben Sie erwartet, wenn keine Kinderprozesse existieren?

+0

Vielen Dank. Ich habe nicht ganz verstanden, was die "nicht erwünschten Kinder" auf der Manpage bedeuten. Meine Erwartung war, dass es blockieren wird, bis es sowieso ein verlassenes Kind gibt (z. B. könnte ein anderer Thread ein Kind starten, das dann austreten könnte). –

+0

Warum sollte es warten, bis ein Zeitgebersignal ausgelöst wird, das einen Handler aufruft, der ein Kind "fork()" und dann auf dieses Kind wartet. :) – Kaz

+0

Ich sollte lieber auf SIGCHLD warten, wenn Signale verwendet werden :) –

1

Der wait() Aufruf funktioniert wie dokumentiert. Was Sie laufen in einem Fehlerzustand in ERRORS Abschnitt beschrieben here:

ECHILD (for wait()) The calling process does not have any unwaited-for 
      children. 

    ECHILD (for waitpid() or waitid()) The process specified by pid (waitpid()) or 
      idtype and id (waitid()) does not exist or is not a child of the 
      calling process. (This can happen for one's own child if the action 
      for SIGCHLD is set to SIG_IGN. See also the Linux Notes section about 
      threads.) 

    EINTR WNOHANG was not set and an unblocked signal or a SIGCHLD was caught; 
      see signal(7). 

    EINVAL The options argument was invalid. 

So ist es nicht blockieren, weil es keinen Sinn, auf Fehler zu blockieren macht.