2013-05-08 57 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

相关问题