2

Is I am looking at writing a multithreaded tcp server using boost ASIO. I have read through the tutorials and had a look at some of the examples and just want to check that my understanding is correct.

The server will accept connections then service requests from multiple clients.

My understanding is as follows:

  1. The server uses "a single io_service and a thread pool calling io_service::run()"
  2. All threads call io_service::run().
  3. The calls to io_service::run() are not within a strand, ergo completion handlers can run simultaneously.
  4. When a request arrives one of the threads is chosen, its read handler will be called
  5. Another request may arrive,starting the read handler on a second thread
  6. When one of the threads has finished handling the request it calls async_write, from within a strand
  7. Another thread also finishes processing its request, it also calls async_write, from within a strand
  8. The writes to the io_service are serialised via the strand, ergo they are thread safe.
  9. When the write operation completes the thread calls async_read()
  10. This call is not protected by a strand and the thread will be used for handling requests

Is my understanding correct? Is this solution vulnerable to race conditions?

mark
  • 7,381
  • 5
  • 36
  • 61
  • 2
    This really is not an answerable question as it is currently written. There is nothing incorrect about your understanding. Are you having specific problems? If so, can you post some code? – Sam Miller Jan 15 '12 at 16:07
  • 1
    I just wanted to confirm tha my assuptions / understanding is correct before going ahead and implementing it. I think you have possibly done that, thanks. I have only had limited experience of asio in the oast and this will be the first time I am planning to use it in anger. – mark Jan 15 '12 at 16:10
  • @mark have you wrote this server? I have looked at several examples of multithread async servers, but it's overhead for me. Could you show yours? – Alex Aug 28 '12 at 07:27

1 Answers1

3

As Sam miller said, your assumptions are quite correct.

However I would like to point out an issue that you may have not spotted.

It is right that strands will serialize async_write(s) and therefore there will be thread safe. But the issue is not here, async_write is by itself thread safe if not used on the same socket. And strands will not help here since you should not interleave async_write on the same socket.

Strands will not wait the previous async_write to finish before calling the next one. you will have to create a structure that async_write only if none is already in action on the socket.

TheSquad
  • 7,385
  • 8
  • 40
  • 79
  • Thanks for your reply. Does this mean that the strand is unnecessary providing I guard against calling async_write on the same socket from more than one thread? – mark Jan 16 '12 at 20:25
  • Actually, strands should be used here but not directly on the async_write but on the queue you should implement to not interleave async_writes. You should find all your answers in one of my question http://stackoverflow.com/questions/7754695/boost-asio-async-write-how-to-not-interleaving-async-write-calls – TheSquad Jan 16 '12 at 21:03
  • Thanks again - Sam Miller's solution looks very elegant – mark Jan 16 '12 at 21:48
  • +1 for "you should not interleave async_write on the same socket" – Arnaud Dec 29 '13 at 09:46