【问题标题】:How to prevent SIGPIPE in multi-thread program?如何防止多线程程序中的 SIGPIPE?
【发布时间】:2018-04-04 15:40:37
【问题描述】:

我写了一个很小的 ​​httpd。但是如果我在短时间内向httpd发送了很多请求,httpd会因为SIGPIPE而退出。

在谷歌上搜索后,我添加了

signal(SIGPIPE, SIG_IGN);
sigset_t signal_mask; 
sigemptyset(&signal_mask); 
sigaddset(&signal_mask, SIGPIPE); 
if(pthread_sigmask(SIG_BLOCK, &signal_mask, NULL) == -1) 
perror("SIGPIPE"); 

send(fd, buf, strlen(buf), MSG_NOSIGNAL);

在我的代码中防止 SIGPIPE。

但是由于 SIGPIPE,httpd 仍然退出。

谁能帮我解决这个问题?

我的代码:

httpd.c

threadpool.c

【问题讨论】:

  • 您是否尝试过使用gdb 进行调试?您可以使用gdb handle SIGPIPE nostop 手动禁用SIGPIPE
  • 您尝试过以多种方式做同样的事情(忽略 SIGPIPE,阻止 SIGPIPE,告诉send 忽略 SIGPIPE)所以它应该真的 i> 工作 ;-) 你确定程序退出是因为 SIGPIPE 而不是其他问题?您如何确定 SIGPIPE 是退出的原因?
  • 进行此更改后,您是否重新构建了应用程序?
  • send 可能只进行部分发送,您的代码无法处理,因为它不检查 send 调用的返回值。
  • 你也应该在这里发布你的代码。

标签: c linux sockets network-programming


【解决方案1】:

通常的方法是忽略 SIGPIPE(signal(SIGPIPE, SIG_IGN); -- 你说你已经完成了),然后 小心 检查 EVERY 写入和发送调用以确保您正在正确检查返回值并处理您收到的任何 EPIPE(或其他)错误。

忽略 SIGPIPE 的危险在于,很容易让程序在写入关闭的连接时运行,忽略错误,并且永不终止。

一旦您忽略 SIGPIPE,您的程序将永远不会因为 SIGPIPE 而退出。

【讨论】:

  • 我使用gcc -g httpd.c -lphtread编译我的代码,并使用strace -i ./httpd跟踪我的程序,它被SIGPIPE杀死了。但是新程序是a.out。所以我在追踪旧程序。 Σ(っ°Д°;)っ。当 strace 正确的程序时,它会成功阻止 SIGPIPE。
猜你喜欢
  • 2017-12-16
  • 2012-07-03
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多