- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在做一项作业,涉及编写一个程序来使用 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
而不是静默终止您的程序。
但是:如果您在写入管道时收到 SIGPIPE
,则不要重试。它永远不会工作。 SIGPIPE
表示管道没有读取器——如果管道现在没有读取器,它将永远不会有读取器。 (想一想:没有读卡器的管道怎么会有读卡器?这不可能!)
您的问题是您正在关闭管道的另一端。解决这个问题,不用担心 SIGPIPE
。 SIGPIPE
只是症状。
编辑:这里有两个问题需要回答。如果您不能回答两个这些问题,那么就不要费心处理SIGPIPE
。
什么会导致我的程序接收到 SIGPIPE
? 接收 SIGPIPE
的唯一方法是管道的读取端关闭。如果读取进程崩溃,或者如果它被编程为关闭管道,就会发生这种情况。如果您正在编写网络服务器,或与未知进程通信,这可能很常见。但是,如果您编写的两个程序都在本地运行,则可能表明存在编程错误。
当我的程序捕获到 SIGPIPE
时会做什么?如果您正在编写一个使用管道与服务器通信的客户端进程,那么什么是你应该用 SIGPIPE
做什么?您不能再试一次,而且客户端通常不能重新启动它们所连接的服务器。只需执行明智的默认操作,然后让 SIGPIPE
终止您的程序。但是,如果服务器正在向它控制的客户端发送数据并获得 SIGPIPE
,它可以重新启动客户端。但这可能是一个非常糟糕的主意——例如,如果客户端是确定性的,它只会再次崩溃,而您最终会陷入无限循环,而不是简单的崩溃。
所以这里的一般格言是“只捕获您准备好处理的错误。”不要仅仅为了完整性而捕获错误。就让他们让你的程序崩溃,或者导致运行失败,你可以稍后回去调试。
代码片段:这是我的一个项目中的一段代码。如果您运行它,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");
}
关于c - 使用信号和 sigpipe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7774569/
在我的示例应用程序中它显示 SIGPIPE 错误,即使我在 main.m 文件中忽略了该信号 #import #import "AppDelegate.h" int main(int argc, c
我正在处理一些代码,这些代码需要安全地防止由于 SIGPIPE 而杀死调用者,但是它正在执行的唯一套接字写入将转到数据报套接字(UDP 和 Unix 域数据报套接字) ).我需要担心 SIGPIPE
我有两个守护进程,A 正在与 B 通信。B 正在监听一个端口,A 打开一个到该端口的 tcp 连接。 A 能够打开一个到 B 的套接字,但是当它尝试实际写入所述套接字时,我得到一个 SIGPIPE,所
我正在尝试从执行工具的 bash 函数中保存一些日志(其中一些在子 shell 中运行)。此外,我想将所有错误打印到终端。 我的代码导致一个 sigpipe 并在按下 ctr-c 加上一个奇怪的日志文
我正在cocoa中开发一个应用程序,它由用java编写的客户端部分组成,监听来自服务器的请求(例如从客户端计算机读取一些歌曲或文件),有时这工作正常,但有时会出现异常,例如“收到信号SIGPIPE”
我在 C 上的服务器/客户端有这个问题。如果我在 SIGINT 之后关闭服务器套接字,然后我尝试从客户端写这个关闭的连接,我必须在客户端生成 SIGPIPE 之前写两次.它不应该立即生成吗?这是正常行
根据我的理解,SIGPIPE 只能作为 write() 的结果发生,它可以(并且确实)返回 -1 并设置 errno 到 EPIPE...那么为什么我们会有额外的信号开销呢?每次我使用管道时,我都会忽
POSIX环境中可能出现的错误有很多。为什么其中一些(特别是写入未连接的套接字)会以信号的形式得到特殊处理? 最佳答案 这是设计使然,因此当消费者死亡时,在管道中使用的生成文本(例如 find、gre
我有一个在 Linux 上运行的应用程序,捕获信号并将它们报告给系统日志。 此应用程序频繁报告 SIGPIPE 事件,没有明显原因 该应用程序作为守护进程在后台运行。信号发生在空闲时间,没有明显的网络
嗨,我必须开发这个程序,创建 4 个 child ,并依次让他们做一个简单的操作。第一个进行求和,第二个进行余数,第三个进行乘法,第四个进行除法。父亲将在套接字上写入他希望 children “计算”
我想知道 tcp 套接字是否可以立即报告任何损坏的管道错误。目前,当服务器出现故障时,我正在客户端捕获 sigpipe 信号......但我发现生成了 sigpipe 信号只有在第二个消息从客户端发送
我在 C 上的服务器/客户端有这个问题。如果我在 SIGINT 后关闭服务器套接字,然后我尝试从客户端写入这个关闭的连接,我必须先写两次客户端生成 SIGPIPE。它不应该立即生成吗?这是正常行为还是
我正在看的代码在这里: http://github.com/andymatuschak/Sparkle/blob/8ea15468b4a8c0487ca7a72f3c9e6ffb708c6af8/SU
我已经阅读了如何防止SIGPIPE,然后我写了一个小程序来测试它。这是代码。 server.c #include #include #include #include #include #i
我正在尝试在 Bash 中的两个进程之间实现命名管道通信解决方案。 第一个进程向命名管道写入内容: send(){ echo 'something' > $NAMEDPIPE } 第二个脚本应
我正在尝试编写一个包含两个进程的程序: 一个进程生成一些 a + b 问题并将其打印到其标准输出(如 printf("%d %d\n", a, b)),并从另一个进程获取答案通过 stdin,并将答案
我有一个在多个线程中共享的套接字连接池,死连接应该从池中删除,问题是我不知道哪个死于 SIGPIPE sighandler,在这种情况下有什么建议吗? 最佳答案 处理此问题的一种方法是忽略 SIGPI
我有一个用 C 编写的多线程 SSL 服务器,其行为如下: 主线程等待客户端请求 (epoll),接受它们并为每个客户端套接字生成一个分离线程 每个线程分别执行SSL_accept。 SSL 握手 成
我正在做一项作业,涉及编写一个程序来使用 fork(进程)、信号和选择来处理数据(计算 pi)。 我现在正在处理信号,我想我想做的是使用 SIGPIPE,所以如果程序捕获它,它会尝试再次写入管道(如果
所以在我的应用程序开始时我调用 signal(SIGPIPE, SIG_IGN); 我认为我的应用程序会忽略 SIGPIPE。但是,我仍然遇到以下代码导致的 SIGPIPE 崩溃: write(fd,
我是一名优秀的程序员,十分优秀!