2013-05-08 17 views
2

我覺得我的代碼將無法打印文本system()在裏面做一個像sem_post這樣的調用嗎?

哦,爲什麼來這裏!\ n

,但它確實。

system()有什麼不對嗎?因爲當我刪除它時,代碼就會按我的意願運行,停止運行。

#include <pthread.h> 
#include <semaphore.h> 
#include <stdio.h> 
#include <stdlib.h> 

pthread_t id0, id1; 
sem_t sp; 

void *fun0(void *) { 
    // When erasing the following line "system("");", 
    // it block up, and doesn't print "oh why come here!\n". 
    // But with it, it print the text! 
    system(""); 
    return NULL; 
} 

void *fun1(void *) { 
    sem_wait(&sp); 
    fprintf(stderr, "oh why come here!\n"); 
    return NULL; 
} 
int main() { 
    sem_init(&sp, 0, 0); 
    pthread_create(&id0, 0, fun0, NULL); 
    pthread_create(&id1, 0, fun1, NULL); 
    void *stat0, *stat1; 
    pthread_join(id0, &stat0); 
    pthread_join(id1, &stat1); 
    return 0; 
} 

編譯器:GCC 4.1.2 Linux內核:2.6.18


我用gcc 4.6.3,內核3.2.0編譯它,它跑了,我想也是。 所以我認爲這是因爲gcc 4.1.2或kernel 2.6.18。

回答

1

問題你的代碼是sem_wait(),從sem_wait手冊頁,它說:

「sem_wait()遞減(鎖定)的信號通過SEM指出,如果信號量的值大於零,那麼遞減就會繼續,函數立即返回,如果信號量當前的值爲零,那麼調用會阻塞,直到有可能執行遞減操作(即信號量值上升到零以上),或者信號處理程序中斷電話「。

在你的代碼中,你用sp初始化爲0,當sem_wait()遞減時,它會阻塞並永遠不會返回,因爲沒有其他線程增加sp變量。

+0

這怎麼可能是正確答案?如果sem_wait被阻塞,那麼下面的printf不會發生。會發生什麼情況是,執行system()的線程會觸發一箇中斷sem_wait的信號(可能是SIGCHILD?)。檢查sem_wait的返回值,你會被修復(如果我是對的,它是-EINTR)。 – xryl669 2013-06-28 16:50:00

+0

你移動這些printf()語句,你會明白爲什麼。 – 2013-06-28 17:07:40

3

system()調用與它無關。我的心理能力告訴我sem_wait失敗,出現錯誤代碼而不是等待檢查返回值。例如,我可以在Mac OS X上重現您的結果,因爲在Mac OS X上,sem_init()始終因ENOSYS(「功能未實現」)而失敗,導致sem_wait調用失敗,出現EBADF(「錯誤文件描述符」) 。

如果你添加一些錯誤檢查,你會看到事情出差錯:

if(sem_init(&sp, 0, 0) < 0) 
    fprintf(stderr, "sem_init failed: %s\n", strerror(errno)); 
... 
if(sem_wait(&sp) < 0) 
    fprintf(stderr, "sem_wait failed: %s\n", strerror(errno)); 

你也應該殺青你的警告級別的編譯器,我絕對推薦使用-Wall-Wextra -pedantic如果你想捕捉更多可能的問題。目前,您的代碼通過未能返回fun0fun1函數的值而調用未定義的行爲-Wall會提醒您。這種錯誤在x86上可能不會導致任何明顯的問題,但在其他體系結構上,如IA64,uninitialized garbage can be deadly

+0

我添加了fun0/1的回報。但很難相信系統(「」)會使sem_wait()失敗。 – 2013-05-08 05:20:20

相關問題