首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用信号和sigpipe

使用信号和sigpipe
EN

Stack Overflow用户
提问于 2011-10-15 07:21:13
回答 1查看 13.3K关注 0票数 5

我正在做一个任务,它涉及到编写一个程序来使用fork (进程)、signals和select来处理数据(计算pi)。

我现在正在处理信号,我想我想要做的是使用SIGPIPE,这样如果程序捕捉到它,它会再次尝试写入管道(如果一个进程试图写入没有读取器的管道,它将被发送SIGPIPE)。

我在main()中使用fork(),通过将它们发送到worker函数来为每个进程分配相同的工作。

代码语言:javascript
复制
void worker(int id) {
    .... (this piece of code is not relevant)

    if(write(pfd[id][1], &c, sizeof(c)) == -1)
        printf("Error occurred: %s\n",strerror(errno));

}

如何在此函数中实现信号以捕获SIGPIPE并使其再次写入管道?

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-10-15 20:19:35

通常,不是捕获SIGPIPE而是忽略它,这会导致write失败并返回EPIPE,而不是静默地终止您的程序。

然而:如果您在写入管道时得到一个SIGPIPE,那么就不要再尝试。它永远不会起作用。SIGPIPE意味着管道没有读取器--如果管道现在没有读取器,它将永远不会有读取器。(这样想一想:没有阅读器的管道怎么会有阅读器?这是不可能的!)

你的问题是你正在关闭管道的另一端。解决这个问题,不用担心SIGPIPESIGPIPE只是一个症状。

编辑:这里有两个问题要回答。如果你不能同时回答这两个问题,那就别费心去处理SIGPIPE了。

  1. What会导致我的程序接收SIGPIPE**?** ,接收SIGPIPE的唯一方法是关闭管道的读取端。如果读取过程崩溃,或者如果它被编程为关闭管道,就会发生这种情况。如果您正在编写网络服务器,或者正在与未知进程通信,这种情况可能很常见。然而,如果你写了两个程序,都在本地运行,那么这可能表明当我的程序捕捉到 error.
  2. What时,它会做一个编程SIGPIPE**?**如果你正在编写一个使用管道与服务器通信的客户端进程,那么你应该对SIGPIPE做什么?您无法重试,并且客户端通常无法重新启动它们所连接的服务器。只要做一件明智的、默认的事情,让SIGPIPE终止你的程序。但是,如果服务器向它控制的客户端发送数据并获取SIGPIPE,它可能会重新启动客户端。但这可能是一个非常糟糕的想法--例如,如果客户端是确定性的,它将再次崩溃,您将以无限循环而不是简单的崩溃而告终。

因此,这里的通用格言是“只捕获您准备处理的错误。”不要仅仅为了完整性而捕获错误。只要让它们使你的程序崩溃,或者导致操作失败,你可以稍后再去调试它。

代码片段:这是我的一个项目的代码片段。如果您运行它,SIGPIPE将不会终止您的进程。相反,write将生成一个EPIPE错误。如果您正在编写网络服务器,那么EPIPE是客户端可能突然断开连接的一种可能方式。

代码语言:javascript
复制
void
ignore_sigpipe(void)
{
    struct sigaction act;
    int r;
    memset(&act, 0, sizeof(act));
    act.sa_handler = SIG_IGN;
    act.sa_flags = SA_RESTART;
    r = sigaction(SIGPIPE, &act, NULL);
    if (r)
        err(1, "sigaction");
}
票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7774569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档