【问题标题】:pclose() returns SIGPIPE intermittentlypclose() 间歇性地返回 SIGPIPE
【发布时间】:2014-04-26 07:22:49
【问题描述】:

当下面的C程序执行,SIGUSR1被反复发送给正在运行的进程时,pclose()调用有时会返回13。13对应我系统上的SIGPIPE

为什么会这样?

我正在使用while true; do kill -SIGUSR1 <process-id>; done 向程序发送SIGUSR1。该程序在 Ubuntu 14.04 上执行。

#include <pthread.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>

void handler(int i) {}

void* task(void*)
{
    FILE *s;
    char b [BUFSIZ];
    while (1) {
        if ((s = popen("echo hello", "r")) == NULL) {
            printf("popen() failed\n");
        }
        while (fgets(b, BUFSIZ, s) != NULL) ;
        if (int r = pclose(s)) {
            printf("pclose() failed (%d)\n", r);
        }
    }

    return 0;
}

int main(int argc, char **argv)
{
    struct sigaction action;
    action.sa_handler = handler;
    sigemptyset(&action.sa_mask);
    action.sa_flags = 0;
    sigaction(SIGUSR1, &action, NULL);

    pthread_t tid;
    pthread_create(&tid, 0, task, NULL);
    pthread_join(tid, NULL);
}

【问题讨论】:

    标签: linux multithreading signals posix popen


    【解决方案1】:

    fgets 被信号中断时会发生这种情况。该程序不会将管道读取到最后并关闭它。另一个程序然后是 SIGPIPE。

    正确的读管操作是:

     do {
        while (fgets(b, BUFSIZ, s) != NULL) ;
     } while (errno == EINTR);
    

    【讨论】:

    • 谢谢。我应该仔细阅读fgets() 文档:“成功完成后,fgets() 应返回 s。如果流位于文件末尾,则应设置流的文件结束指示符并 fgets( ) 应返回空指针。如果发生读取错误,则应设置流的错误指示符,fgets() 应返回空指针,并应设置 errno 以指示错误。"
    猜你喜欢
    • 1970-01-01
    • 2019-12-05
    • 1970-01-01
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    • 2014-11-09
    • 1970-01-01
    相关资源
    最近更新 更多