如何在使用boost::asio时防止SIGPIPE
How do I prevent SIGPIPE when using boost::asio?
我使用管道在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)
手册页
EPIPE
fd连接读端关闭的管道或插座。当在这种情况下,写入进程也将接收到SIGPIPE信号。(因此,写返回值只在程序捕获,阻塞或忽略此信号)
SIGPIPE是在管道的一端未连接时由操作系统生成的-您无法使用boost::asio来真正阻止它。但是,您可以简单地忽略该信号,其余部分应该自行处理。
signal_init
已经在文件boost/asio/detail/signal_init.hpp
中做过了
相关文章:
- 理解boost::asio-async_read在无需读取内容时的行为
- 提升 ASIO 无法识别计时器对象
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- boost::asio::steady_timer()与sleep()我应该使用哪一个
- boost::asio如何生成多个协同程序,然后加入它们
- 缓慢提升ASIO
- 从 Boost ASIO 获取 epoll 描述符 io_service对象
- 如何在 Boost.Asio 中使用 Zero-copy sendmsg/receive
- C++ Boost::asio串行通信与Arduino无法写入
- 如何使用 Boost Asio 在 Android 上获取我的本地 udp IP 地址?
- 提升 Asio TCP 服务器 处理多个客户端
- boost::asio UDP 广播客户端仅接收"fast"数据包
- 提升 ASIO - io_service 不要等待连接到线程
- 执行时使用 boost::asio::d eadline_timer 时出错
- Boost.Asio/OpenSSL HTTPS GET certificate trouble
- C++ boost::asio::ip::tcp::acceptor 有时不接受连接器?
- boost::asio data owning `ConstBufferSequence`
- 如何替换此示例代码片段中已弃用的handler_type_t或 boost::asio::handler_type?
- ASIO如何处理Sigpipe
- 如何在使用boost::asio时防止SIGPIPE