Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are Asynchronous writes to a socket thread safe?

Consider the Socket.BeginSend() method. If two thread pool threads were to call this method simultaneously, would their respective messages end up mixing with each other or does the socket class keep this from happening?

like image 687
Dabloons Avatar asked Apr 13 '12 18:04

Dabloons


People also ask

Is writing to socket thread safe?

Generally they are not thread safe since send is not an atomic operation.

Is ASIO thread safe?

Asio socket, a stream is not thread safe. Callers are responsible for synchronizing operations on the socket using an implicit or explicit strand, as per the Asio documentation.

Is socket close thread safe?

Therefore: If a single thread is invoking io_service::run() and socket. close() is invoked from within a handler, then it is safe as there is no possibility of concurrent execution.

Are Python sockets thread safe?

Unfortunately,The socket shared by multi-thread is not thread safe. Think about buffer two threads operate on with no lock.


1 Answers

.NET Socket instances are not thread-safe in that simultaneous calls to some methods (the same or different ones) may cause inconsistent state. However, the BeginSend() and BeginReceive() methods are thread-safe with respect to themselves.

It is safe to have multiple outstanding calls to each (or both).

In the case of BeginReceive(), they will be serviced when data is available in the order called. This can be useful if, for example, your processing is lengthy but you want other receives to occur as quickly as possible. Of course in this case you may have your code processing multiple receipts simultaneously and you may need your own synchronization logic to protect your application state.

In the case of BeginSend(), each call will attempt to push the sent data into the socket buffer, and as soon as it is accepted there, your callback will be called (where you will call EndSend()). If there is insufficient buffer space for any call, it will block.

Note: don't assume that the default 8k buffer means "I can quickly call BeginSend() with exactly 8k of data, then it will block," as the following are true:

  1. The 8K is a "nominal size" number, and the buffer may shrink and grow somewhat

  2. As you are queing up the 8K worth of calls, data will be being sent on the network reducing that 8K of queued data

In general:

  • If you call BeginSend() several times within a thread, you are assured that the sends will leave the machine in the order they were called.

  • If you call BeginSend() from several threads, there is no guarantee of order unless you use some other blocking mechanism to force the actual calls to occur in some specific order. Each call however will send its data properly in one contiguous stream of network bytes.

like image 197
Scott Hooper Avatar answered Oct 23 '22 20:10

Scott Hooper