【问题标题】:How asio deal with SIGPIPE?asio如何处理SIGPIPE?
【发布时间】:2017-09-07 06:26:38
【问题描述】:

Asio 有代码可以忽略 Signal_init.hpp 中的 SIGPIPE,但是在 io_service.hpp 中有一个宏扭曲它:

#elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \
  || defined(__osf__)

我在 Ubuntu 中编译发现宏没有启用,所以 std::signal(Signal, SIG_IGN); 没有被调用。

但是,当我通过 asio 写入关闭的套接字时,它可以通过完整处理程序中的 boost::system::error_code 报告 EPIPE 错误。根据libc doc

在这种情况下,send 先生成一个 SIGPIPE 信号;如果那个信号是 忽略或阻止,或者如果其处理程序返回,则发送失败 外延。

asio 如何用SIGPIPE 设置让进程忽略它? asio 在这方面有什么特别之处吗?

【问题讨论】:

    标签: c++ boost-asio


    【解决方案1】:

    您可以简单地告诉操作系统您希望SIGPIPE 被忽略。

    Asio 在 http://www.boost.org/doc/libs/1_65_1/boost/asio/detail/signal_init.hpp 有代码可以做到这一点

    奇怪的是(?)它只包含在老式 UNIX 中:

    #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
    # include <boost/asio/detail/winsock_init.hpp>
    #elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \
      || defined(__osf__)
    # include <boost/asio/detail/signal_init.hpp>
    #endif
    

    你可以自己做:

    #include <csignal>
    
    // ...
    std::signal(SIGPIPE, SIG_IGN);
    

    或者你可以使用 Asio 信号集类:

    #include <boost/asio.hpp>
    #include <boost/asio/signal_set.hpp>
    #include <iostream>
    
    boost::asio::io_service svc;
    boost::asio::signal_set ss(svc);
    
    static void ignore_signal(boost::system::error_code ec, int /*signal*/) {
        if (!ec) ss.async_wait(ignore_signal);
        // std::cout << "\n" << ec.message() << "\n";
    }
    
    int main() {
        ss.add(SIGPIPE);
        ss.add(SIGINT);
        ss.async_wait(ignore_signal);
        svc.run();
    }
    

    【讨论】:

    • 我很好奇 asio 是如何处理这个问题的。它没有忽略 SIGPIPE,没有使用 MSG_NOSIGNAL。但是当我继续写入断开连接的套接字时,根本没有 SIGPIPE!
    猜你喜欢
    • 1970-01-01
    • 2011-12-20
    • 2021-05-19
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 2014-09-15
    • 1970-01-01
    相关资源
    最近更新 更多