gpt4 book ai didi

c++ - 使用 boost::asio 时如何防止 SIGPIPE?

转载 作者:IT老高 更新时间:2023-10-28 22:39:15 26 4
gpt4 key购买 nike

我正在使用管道在 Gnu/Linux 上的两个进程之间进行通信。接收端关闭管道,而发送端仍在尝试发送数据。这是一些模拟这种情况的代码。

#include <unistd.h>                                                              
#include <boost/asio.hpp>

int main()
{
int pipe_fds[2];
if( ::pipe(pipe_fds) != 0 ) return 1;
// close the receiving end
::close( pipe_fds[0] );

boost::asio::io_service io;
boost::asio::posix::stream_descriptor sd( io, pipe_fds[1] );
boost::system::error_code ec;
sd.write_some( boost::asio::buffer("blah"), ec );

return 0;
}

当我运行它时,我得到一个 SIGPIPE;经典的情况,我知道。但是,我看到 boost::asio::error::basic_errors 有一个 broken_pipe 值。我希望它会在 error_code 中返回而不会引发信号。

可以在不为我的进程创建 SIGPIPE 处理程序的情况下完成此操作吗?例如,是否有我缺少的 boost::asio 配置选项?也许可以在实现中启用 MSG_NOSIGNAL?

最佳答案

如果您希望看到适当的 error_code

,请安装一个信号处理程序以忽略 SIGPIPE

编码和编译

#include <unistd.h>
#include <iostream>
#include <boost/asio.hpp>


int main( int argc, const char** argv )
{
bool ignore = false;
if ( argc > 1 && !strcmp(argv[1], "ignore") ) {
ignore = true;
}
std::cout << (ignore ? "" : "not ") << "ignoring SIGPIPE" << std::endl;

if ( ignore ) {
struct sigaction sa;
std::memset( &sa, 0, sizeof(sa) );
sa.sa_handler = SIG_IGN;
int res = sigaction( SIGPIPE, &sa, NULL);
assert( res == 0 );
}

int pipe_fds[2];
if( ::pipe(pipe_fds) != 0 ) return 1;
// close the receiving end
::close( pipe_fds[0] );

boost::asio::io_service io;
boost::asio::posix::stream_descriptor sd( io, pipe_fds[1] );
boost::system::error_code ec;
sd.write_some( boost::asio::buffer("blah"), ec );

if ( ec ) {
std::cerr << boost::system::system_error(ec).what() << std::endl;
} else {
std::cout << "success" << std::endl;
}

return 0;
}

samjmill@bgqfen7 ~> g++ pipe.cc -lboost_system -lboost_thread-mt
samjmill@bgqfen7 ~>

运行

samm@macmini ~> ./a.out 
not ignoring SIGPIPE
samm@macmini ~> echo $?
141
samm@macmini ~> ./a.out ignore
ignoring SIGPIPE
Broken pipe
samm@macmini ~>

这种行为的基本原理是在 write(2) man page

EPIPE

fd is connected to a pipe or socket whose reading end is closed. When this happens the writing process will also receive a SIGPIPE signal. (Thus, the write return value is seen only if the program catches, blocks or ignores this signal.)

我添加的重点。

关于c++ - 使用 boost::asio 时如何防止 SIGPIPE?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7987014/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com