Search code examples
c++asynchronousboostsynchronizationboost-asio

Boost Asio Sync vs Async


I use Boost Asio for the first time and I'm having a application that accepts multiple connections, each in separate threads and read/write data to a single tcp socket.

My understanding of sync method is that every thread before using the fd, they need to make sure that it's free using a call like select()/WSAEventSelect(), WaitForSingleObject().

So sync method has this waiting for the resource to become available to it.

But what about async method?

Let's say I have a socket and doing async_accept() for accepting connections, async_read() for receiving and async_write() for sending. Since in async method the resource/socket is not kept, do I still need to wait for it to become available?

In the beginning of this question I explained what I'm trying to do, so please forgive if my understanding of the problem an what came next is not accurate.

Thanks for understanding


Solution

  • I think most of your explanation is sadly upside down. Picking out the most obvious ones:

    My understanding of sync method is that every thread before using the fd, they need to make sure that it's free using a call like select()/WSAEventSelect(), WaitForSingleObject().

    On the contrary, select (poll/epoll) are useful for asynchronous handling of events (like incoming data available or error condition). They are not used/useful for synchronous operations, because they will just block until the state is reached.

    Maybe you're imagining that the kernel implements that "as if" synchronizing with a thread synchronization primitive. Fair enough, though probably not very accurate, the effect is that: the call blocks.

    This style of communication is limited even with a thread-per-connection as it will never allow full-duplex communication, which means some protocols are prone to deadlocks.

    Let's say I have a socket and doing async_accept() for accepting connections, async_read() for receiving and async_write() for sending. Since in async method the resource/socket is not kept, do I still need to wait for it to become available?

    Yes and no. If you were doing asynchronous BSD sockets by hand, YES, you would actually need to poll for socket events, like mentioned above.

    The whole purpose of Asio is to make this transparent in a platform-independent way, while also leveraging a boat load of good practices and optimizations. Therefore, NO you don't need to wait for [the socket] to become available.

    Since in async method the resource/socket is not kept

    But it is. It is kept by the service implementation which lives in the execution context (io_context). The tcp::socket (or other basic_stream_socket instance) is your "handle". So the socket is kept and the service knows when/how to wait for low-level states/events.

    I could give you an example of how I'd implement what you describe, but I have a lot of answers on this site that already show. If you have more specific questions, you're welcome to ask them.