【问题标题】:Using signals and sigpipe使用信号和 sigpipe
【发布时间】:2011-12-08 03:25:10
【问题描述】:

我正在处理一项任务,其中涉及编写程序以使用 fork(进程)、信号和选择来处理数据(计算 pi)。

我现在正在处理信号,我想我想做的是使用 SIGPIPE,所以如果程序捕获它,它会尝试再次写入管道(如果进程尝试写入管道没有阅读器,它将被发送 SIGPIPE)。

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

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 并使其再次写入管道?

谢谢!

【问题讨论】:

  • 您应该返回并接受您提出的问题的答案。人们不太可能回答你的问题,因为你不接受他们的答案。
  • 哦,对不起!我会去做。编辑:完成!我是这个网站的新手,它是如何工作的,但我现在明白了 :)

标签: c process pipe signals sigpipe


【解决方案1】:

通常,而不是捕获 SIGPIPE 会忽略它,这会导致 writeEPIPE 失败,而不是静默终止您的程序。

但是:如果您在写入管道时收到SIGPIPE,请不要再试一次。它永远不会起作用。 SIGPIPE 表示管道没有阅读器——如果管道现在没有阅读器,它将永远不会有阅读器。 (这样想:没有阅读器的管道怎么会得到一个?这是不可能的!)

您的问题是您正在关闭管道的另一端。解决这个问题,不要担心SIGPIPESIGPIPE 只是表象。

编辑:这里有两个问题需要回答。如果您不能两个回答这两个问题,那么请不要理会SIGPIPE

  1. 什么会导致我的程序接收SIGPIPE 接收SIGPIPE 的唯一方法是关闭管道的读取端。如果读取过程崩溃,或者它被编程为关闭管道,就会发生这种情况。如果您正在编写网络服务器,或与未知进程通信,这可能很常见。但是,如果您编写的两个程序都在本地运行,那么它可能表示编程错误。

  2. 当我的程序捕获 SIGPIPE 时会做什么? 如果您正在编写一个使用管道与服务器通信的客户端进程,那么您应该如何处理SIGPIPE?您无法重试,客户端通常无法重新启动它们所连接的服务器。只需做明智的默认操作,让SIGPIPE 终止您的程序。但是,如果服务器正在向它控制的客户端发送数据并获得SIGPIPE,它可以重新启动客户端。但这可能是一个非常糟糕的主意——例如,如果客户端是确定性的,它会再次崩溃,您最终会陷入无限循环而不是简单的崩溃。

所以这里的一般格言是“只捕获你准备处理的错误。”不要仅仅为了完整性而捕获错误。只要让他们让你的程序崩溃,或者导致操作失败,你就可以稍后回去调试它。

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

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");
}

【讨论】:

  • 我的程序运行良好,我没有收到任何错误(甚至没有 SIGPIPE)。我在想“如果我得到 SIGPIPE”
  • 如果你没有收到SIGPIPE,那你为什么需要处理呢?
  • 我不知道,但是如果该程序将分发给许多计算机并且其中一台获得 SIGPIPE,那么通过防止这些情况,我将成为一名优秀的程序员。那就是我所想的。如果我不对,请告诉我:)
  • @andrepcg 在 sigpipe 上终止通常是好的行为。例如在cat bigfile | grep -v ballast | head -n 100 中,grep 和 cat 在收到SIGPIPE 时终止是正确的。否则,他们将不必要地挂起或处理大文件的其余部分。
  • It is impossible! 命名管道呢?
猜你喜欢
  • 2021-05-19
  • 1970-01-01
  • 1970-01-01
  • 2013-09-26
  • 2016-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多