2012-04-15 53 views
0

我在Linux上有一個相對簡單的pthread程序。爲此,我已經將它剝離成小片,最後貼出來。wait()不會阻塞,在Linux和pthreads

等待(2)的所有手冊頁都說wait()將被阻塞,除非使用WNOHANG(甚至不能指定wait())。縱觀桁架輸出,它只是一個不停重複:

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

再次,看着wait4(2)的手冊頁,它說,返回的結果是相同waitpid函數()和waitpid函數應該塊除非有WNOHANG,和桁架表明呼叫用的選項是0

作爲參考提出,這是:

  • 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
  • 編譯: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; 

} 

回答

1

wait()也將立即返回,如果沒有子進程來等待,以價值-1errno設置爲ECHILD(這是你的strace是顯示你)。在沒有兒童程序的情況下你期待它做什麼?

+0

謝謝。我不太明白man page中「unwaited-for children」的意思。我的期望是,它會阻止,直到有一個退出的孩子(例如另一個線程可能會啓動一個可能會退出的孩子)。 – 2012-04-15 06:54:33

+0

爲什麼它應該等待定時器信號關閉,這將調用一個處理程序,它將'fork()'一個孩子,然後等待那個孩子。 :) – Kaz 2012-04-17 17:37:53

+0

我寧可等待SIGCHLD,如果使用信號:) – 2012-05-22 16:35:54

1

wait()通話按文件記錄工作。你正在運行到是ERRORS部分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. 

因此,它不會阻止,因爲它沒有意義的阻塞錯誤。