Why doesn't boost::asio::ip::udp::socket::receive_from throw interruption exception in Windows?


volatile std::sig_atomic_t running = true;

int main()
  boost::asio::thread_pool tpool;
  boost::asio::signal_set signals(tpool, SIGINT, SIGTERM);
  signals.async_wait([](auto && err, int) { if (!err) running = false; });

    std::array<std::uint8_t, 1024> data;
    socket.recieve_from(boost::asio::buffer(data), ....); // (1)
    // calc(data);
  return 0;

If my code is blocked in the (1) line in Linux and I try raise the signal, for example, with htop then the line (1) throws exception about the interruption but in Windows it doesn’t. The problem in what I don’t know how to exit the application.

What needs to do my program works equally in both OSs? Thanks.

Use Windows 10 (msvc 17), Debian 11 (gcc-9), Boost 1.78.


Regardless of the question how you "raise the signal" on Windows there’s the basic problem that you’re relying on OS specifics to cancel a synchronous operation.

Cancellation is an ASIO feature, but only for asynchronous operations. So, consider:

signals.async_wait([&socket](auto&& err, int) {
    if (!err) {

Simplifying without a thread_pool gives e.g.:

Live On Coliru

#include <boost/asio.hpp>
namespace asio = boost::asio;
using asio::ip::udp;
using boost::system::error_code;

struct Program {
    Program(asio::any_io_executor executor)
        : signals_{executor, SIGINT, SIGTERM}
        , socket_{executor} //
        signals_.async_wait([this](error_code ec, int) {
            if (!ec) {

        socket_.bind({{}, 4444});

    asio::signal_set signals_;
    udp::socket      socket_;

    std::array<std::uint8_t, 1024> data_;
    udp::endpoint                  ep_;

    void receive_loop() {
        socket_.async_receive_from( //
            asio::buffer(data_), ep_, [this](error_code ec, size_t) {
                if (!ec)

int main() {
    asio::io_context ioc;
    Program app(ioc.get_executor());

    using namespace std::chrono_literals;
    ioc.run_for(10s); // for COLIRU

Prints (on coliru):

@asio|1663593973.457548|0*1|[email protected]_wait
@asio|1663593973.457687|0*2|[email protected]_receive_from
@asio|1663593974.467265|2*3|[email protected]_receive_from
@asio|1663593975.481854|3*4|[email protected]_receive_from
@asio|1663593976.494150|4*5|[email protected]_receive_from
@asio|1663593976.495119|1|[email protected]
@asio|1663593976.495184|0|[email protected]
@asio|1663593976.495244|0|[email protected]

So that’s 3 successful receives, followed by a signal 2 (INT) and cancellation which results in ec=125 (asio::error:operation_aborted) and shutdown.

enter image description here


There’s likely no gain for using multiple threads, but if you do, use a strand to synchronize access to the IO objects:

asio::thread_pool ioc;
Program app(make_strand(ioc));

Answered By – sehe

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published