- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在为 Linux 上的 TCP 连接编写 C++ SSL 服务器。当程序使用 SSL_write()
写入关闭的管道时,会抛出 SIGPIPE 异常,导致程序关闭。我知道这是正常行为。但是当对等方没有正确关闭连接时,程序不应该总是死掉。
我已经在谷歌上搜索了很多,并尝试了几乎所有我发现的东西,但似乎没有什么对我有用。 signal(SIGPIPE,SIG_IGN)
不起作用 - 仍然会抛出异常(与 signal(SIGPIPE, SomeKindOfHandler)
相同。
gdb 输出:
Program received signal SIGPIPE, Broken pipe.
0x00007ffff6b23ccd in write () from /lib/x86_64-linux-gnu/libpthread.so.0
(gdb) where
#0 0x00007ffff6b23ccd in write () from /lib/x86_64-linux-gnu/libpthread.so.0
#1 0x00007ffff7883835 in ?? () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
#2 0x00007ffff7881687 in BIO_write () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
#3 0x00007ffff7b9d3e0 in ?? () from /lib/x86_64-linux-gnu/libssl.so.1.0.0
#4 0x00007ffff7b9db04 in ?? () from /lib/x86_64-linux-gnu/libssl.so.1.0.0
#5 0x000000000042266a in NetInterface::SendToSubscribers(bool) () at ../Bether/NetInterface.h:181
#6 0x0000000000425834 in main () at ../Bether/main.cpp:111
关于代码:
我正在使用一个正在等待新连接并接受它们的线程。然后线程将连接信息(BIO 和 SSL)放入 NetInterface
类内的静态映射中。每 5 秒 NetInterface::sendTOSubscribers()
从 main()
执行一次。此函数访问静态映射并将数据发送到其中的每个连接。这个函数也是 SIGPIPE 的来源。我在 main()
(显然在 5 秒循环之前)和 NetInterface::SendToSubscribers()
中使用了 signal(SIGPIPE,SIG_IGN)
>,但它在任何地方都不起作用。
感谢您的帮助!
最佳答案
您必须调用函数 sigaction 来更改此行为,以忽略 SIGPIPE 或使用您自己的信号处理程序以特定方式处理它。请不要使用函数信号,它已过时。
http://man7.org/linux/man-pages/man2/sigaction.2.html
一种方法(我没有编译这段代码,但应该是这样的):
void sigpipe_handler(int signal)
{
...
}
int main()
{
struct sigaction sh;
struct sigaction osh;
sh.sa_handler = &sigpipe_handler; //Can set to SIG_IGN
// Restart interrupted system calls
sh.sa_flags = SA_RESTART;
// Block every signal during the handler
sigemptyset(&sh.sa_mask);
if (sigaction(SIGPIPE, &sh, &osh) < 0)
{
return -1;
}
...
}
如果程序是多线程的,情况会有所不同,因为您对接收信号的线程的控制较少。这取决于信号的类型。对于 SIGPIPE,它将被发送到生成信号的 pthread。尽管如此,sigaction 应该可以正常工作。
可以在主线程中设置掩码,所有随后创建的 pthreads 将继承信号掩码。否则,可以在每个线程中设置信号掩码。
sigset_t blockedSignal;
sigemptyset(&blockedSignal);
sigaddset(&blockedSignal, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &blockedSignal, NULL);
但是,如果您阻止信号,它将等待处理,并会尽快交付。对于这种情况,请在线程末尾使用 sigtimedwait。在主线程或生成 SIGPIPE 的线程中设置的 sigaction 也应该有效。
关于C++ 和 OpenSSL : SIGPIPE when writing in closed pipe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32040760/
我有管道输出 command_a | command_b | ... | command_n 输出是一个数字序列 4.2 -1 ... 0.2 我可以使用 gnuplot 绘制这些数字吗? (将 gn
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 6 年前。 Improv
我目前正在尝试连接父项和子项之间的管道。子级正在执行 sort 并对从父级接收到的输入进行排序。然后 children 写入一个单独的管道。每个进程有两个管道。一个这样 parent 可以将输入发送给
最近我正在研究 Python 中的并行编程工具。这是 os.pipe 和 multiprocessing.Pipe 之间的两个主要区别。(尽管它们被使用的场合) os.pipe是单向,multipro
我的站点上运行着 Yahoo Pipe,Romneyomics它使用来自 Delicious 和 Topsy 的饲料。Delicious 提要不提供“描述”字段,但 Topsy 提供,并且不仅仅是一个
我有一些使用管道的 Haskell 代码: module Main(main) where import Pipes a :: Producer Int IO () a = each [1..10]
所以标题几乎解释了我的问题。 stdout=subprocess.PIPE 和 stdout=PIPE 有什么区别?两者都来自 subprocess 模块,但为什么要使用一个而不是另一个呢?你如何使用
我有一个名为“myPipe”的自定义管道。我得到: The pipe 'myPipe' could not be found error 在我的单元测试中请建议在我的 .spec.ts 中导入和声明什
我有一个非常简单的 Python 3 脚本: f1 = open('a.txt', 'r') print(f1.readlines()) f2 = open('b.txt', 'r') print(f
我正在使用管道和 Python 的多处理模块在进程之间发送简单的对象。文档指出,如果管道已关闭,则调用 pipe.recv() 应该引发 EOFError。相反,我的程序只是阻塞在 recv() 上,
我在 perl 中见过这两种形式的管道 open。 一种是简单的管道打开 open FH,'| command'; 其他是安全管道打开 open FH,'|-','command'; 现在,第二个中的
我正在尝试对我的组件进行单元测试,但它立即生成一个错误: 类型错误:this.store$.pipe 不是函数 根据我的理解, createSpyObj 应该模拟状态。我有不同的选项选项,但没有一个起
我在这里看到这个帖子很多次了;但未能从命令中捕获故意错误。迄今为止我找到的最好的部分工作.. from Tkinter import * import os import Image, ImageTk
我正在编写一个简单的程序来解析编译器的输出并重新格式化任何错误消息,以便我们使用的 IDE(visual studio)可以解析它们。我们使用 nmake构建,它将使用如下命令行调用编译器: cc16
我有一个在coreos上运行的kubernetes集群。我希望在称为记录的Pod中的容器中运行journal2gelf https://github.com/systemd/journal2gelf。
为什么当管道中没有写入器时,读取器存在可以,但当管道中没有读取器时,写入器存在就不行? 。是不是因为reader需要等待,所以没有writer也没关系,而writer已经准备好数据了,即使数据准备好了
我在/etc/postfix/master.cf 中创建了一个 postfix 命令管道,其中包含一个在 STDOUT 和 STDERR 上产生输出的有效命令。在终端上调用时一切正常(因此在 STDO
我有一个命令需要来自管道的输入。例如,考虑著名的 cat 命令: $ echo Hello | cat Hello 假设我在 Perl 6 程序中有一个字符串,我想将其通过管道传递给命令: use v
因此,由于我们拥有各种设置,我习惯于遇到需要将一个可观察结果添加到另一个结果的地方,然后同时使用两者。我需要第一个在另一个之前完成的地方 getUser() .pipe( mergeMap
我在 Angular 5 中有一个非常简单的管道 import { Pipe, Injectable } from '@angular/core'; @Pipe({ name: "defaul
我是一名优秀的程序员,十分优秀!