我正在做一项作业,涉及编写一个程序来使用 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 并使其再次写入管道?
谢谢你!
通常,而不是捕获SIGPIPE
有人忽视它,这会导致write
失败EPIPE
而不是默默地终止你的程序。
However:如果您得到的是SIGPIPE
当您写入管道时,请不要重试。它永远不会起作用。SIGPIPE
意味着管道没有读取器——如果管道现在没有读取器,它将永远不会有读取器。 (这样想:没有读卡器的管道怎么能得到一个读卡器?这是不可能的!)
你的问题是你正在关闭管道的另一端。解决这个问题,不用担心SIGPIPE
. SIGPIPE
只是症状。
Edit:这里有两个问题需要回答。如果你无法回答both这些问题,那就不用费心去处理SIGPIPE
.
什么会导致我的程序收到SIGPIPE
?唯一的接收方式SIGPIPE
用于关闭管道的读取端。如果读取进程崩溃,或者被编程为关闭管道,就会发生这种情况。如果您正在编写网络服务器,或与未知进程通信,这可能很常见。但是,如果您编写的两个程序都在本地运行,则可能表示存在编程错误。
当我的程序捕获时会做什么SIGPIPE
?如果您正在编写一个使用管道与服务器通信的客户端进程,那么您应该做什么SIGPIPE
?您无法重试,并且客户端通常无法重新启动它们所连接的服务器。只需做明智的、默认的事情,然后让SIGPIPE
终止你的程序。但是,如果服务器正在向客户端发送数据,它会控制并获取SIGPIPE
, it could重新启动客户端。但这可能是一个非常糟糕的主意——例如,如果客户端是确定性的,它就会再次崩溃,最终会陷入无限循环而不是简单的崩溃。
所以这里的一般格言是“只捕获您准备处理的错误。“ 不要仅仅为了完整性而捕获错误。只要让它们使你的程序崩溃,或者导致操作失败,然后你就可以回去调试它。
代码片段:这是我的一个项目中的一段代码。如果你运行它,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");
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)