2

我认为我的代码不会打印文本

哦,为什么来这里!\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 或内核 2.6.18。

4

2 回答 2

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如果你想发现更多可能的问题。目前,您的代码通过无法从您的和函数返回值来调用未定义的行为,这会警告您。这种错误在 x86 上可能不会导致任何明显的问题,但在 IA64 等其他架构上,未初始化的垃圾可能是致命的。fun0fun1-Wall

于 2013-05-08T05:09:15.580 回答
1

您的代码的问题在于 sem_wait(),来自 sem_wait 手册页,它说:

“sem_wait() 递减(锁定)sem 指向的信号量。如果信号量的值大于零,则递减继续,函数立即返回。如果信号量当前的值为零,则调用阻塞,直到要么可以执行递减(即,信号量值上升到零以上),要么信号处理程序中断调用。”

在您使用 sp 初始化为 0 的代码上,当 sem_wait() 递减时,它会阻塞并且永远不会返回,因为没有其他线程递增 sp 变量。

于 2013-05-08T05:22:02.920 回答