CentOS上的' signal '函数:意外行为
`signal` function on CentOS: unexpected behavior
我需要禁用CentOS应用程序上的SIGPIPE
,因为这个信号在Internet连接不稳定的情况下工作时会使我的应用程序崩溃。我在main
函数中使用以下代码:
signal(SIGPIPE, SIG_IGN);
然而,程序仍然崩溃与SIGPIPE
。原因是什么?我是否需要在每个线程上调用这个函数,或者调用main
函数就足够了,程序将全局忽略SIGPIPE
?如果它不需要在每个线程上调用,为什么SIGPIPE
仍然崩溃程序,如果它应该忽略信号?
这是一个代码示例,可以让您在linux上设置自己的信号处理程序,捕获SIGPIPE并使用它做一些事情。
#include <signal.h>
#include <unistd.h>
#include <cerrno>
#include <system_error>
#include <iostream>
static sigset_t theMask;
static int count = 0;
static void
signalWrapper(
int theSignalNumber,
siginfo_t* theSignalDescription,
void* theUserContext)
{
// Do something here as reaction to you SIGPIPE
// This is better way to react on such things
std::cout << "Got signal " << theSignalNumber << std::endl;
// Reinstall handler
struct ::sigaction sa;
sa.sa_sigaction = &signalWrapper;
sa.sa_mask = theMask;
sa.sa_flags = SA_SIGINFO;
try
{
if (::sigaction(theSignalNumber, &sa, NULL) == -1)
throw std::error_code(errno, std::system_category());
}
catch (const std::error_code& ec)
{
std::cerr << ec << std::endl;
}
count++;
}
void
setupSignalHandlers()
{
struct ::sigaction sa;
// Prepare mask
sigemptyset(&theMask);
sigaddset(&theMask, SIGPIPE);
// Add some more if you need it to process
sa.sa_mask = theMask;
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = &signalWrapper;
// Perform setup
try
{
if (::sigaction(SIGPIPE, &sa, NULL) == -1)
throw std::error_code(errno, std::system_category());
}
catch (const std::error_code& ec)
{
std::cerr << ec << std::endl;
}
}
int
main()
{
std::cout << "Set handler!" << std::endl;
setupSignalHandlers();
std::cout << "Emit 5 SIGPIPE signals" << std::endl;
while (count < 5)
{
kill(getpid(), SIGPIPE);
usleep(100);
}
return 0;
}
和输出:
Set handler!
Emit 5 SIGPIPE signals
Got signal 13
Got signal 13
Got signal 13
Got signal 13
Got signal 13
我提供信号处理程序,因为处理中断应用程序的信号比忽略它更正确。也许你需要重新建立连接或做一些其他的事情。
根据Signal(2)的手册页," Signal()在多线程进程中的效果是未指定的。"您可以尝试在创建任何其他线程之前在主线程中调用signal(),但不能保证它能工作。
在任何情况下都不赞成signal(),所以我建议切换到sigaction()。我一直在多线程应用程序中使用它,没有任何问题。
相关文章:
- 在C++中对T*类型执行std::move的意外行为
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 处理除以零会导致<csignal>意外行为
- vscode下的Arduino代码出现意外编译错误
- 使用++运算符会导致意外的结果
- 套接字读取后,我在缓冲区中看到意外输入
- 更改.cpp程序的输入文件中数据的位置会意外更改输出
- 使用vscode调试时,GDB意外退出
- 此测试()中发生了什么意外过程?为什么总是覆盖 ch[0 1 2..]?
- 尝试将字符串/字符转换为整数会产生意外结果
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- C++标头错误 C2238 意外标记";"
- C++中意外的多头值
- vector.size() 在比较中意外工作
- 使用 malloc() 时出现意外大小
- 多线程程序中出现意外的内存泄漏
- 为什么static_cast基础类型的枚举类int8_t获得意外值?
- 字符串比较中的意外输出
- 我的代码中的意外价值以及我如何修复它
- CentOS上的' signal '函数:意外行为