我需要在CentOS应用程序上禁用SIGPIPE
,因为当它与不稳定的Internet连接一起工作时,此信号会崩溃我的应用程序。
我在main
函数中使用以下代码:
signal(SIGPIPE, SIG_IGN);
但是,程序仍然与SIGPIPE
崩溃。是什么原因?我是否要在每个线程上调用此函数,或者只需调用main
函数,程序将全局忽略SIGPIPE
?如果不需要在每个线程上调用,为什么SIGPIPE
如果忽略该信号仍会导致程序崩溃?
答案 0 :(得分:1)
这是一个代码示例,它允许您在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
我提供信号处理程序,因为处理打破你的应用程序的信号比忽略它更正确。也许你需要重新建立联系或做其他事情。
答案 1 :(得分:1)
根据Signal(2)的手册页,“未指定多线程进程中信号()的影响。”在创建任何其他线程之前,您可能会尝试确保在主线程中调用signal(),但不能保证它能够正常工作。
在任何情况下都不推荐使用signal(),所以我建议切换到sigaction()。我一直在多线程应用程序中使用它而没有任何问题。