Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is winsock2 thread safe?

I am writing a small 3 servers and 1 client program. the 2 servers send tcp messages and the last one sends upd datagrams using winsock2.

I am wondering if i can make simulanious recvfrom() by using threads (OpenMP or boost::threads) so that 2 threads listen from the same socket on the same port at the same time.

I am using VC++ 2010 on windows7.

Thank you for your help.

like image 938
ezzakrem Avatar asked Dec 21 '12 02:12

ezzakrem


People also ask

Is close () thread-safe?

close() is not thread-safe #120.

Is Getaddrinfo thread-safe?

getaddrinfo() is thread safe. All (or almost all) function man pages have information on thread-safety. Reentrant means thread safe.

Is Zmq_send thread-safe?

The ZMQ Sockets are not thread-safe and they should not be shared between threads. Therefore, the ZMQ Guide recommends creating a dedicated inproc socket for each thread.


2 Answers

Yes, sockets are thread-safe, however you have to be careful. One common pattern (when using blocking IO) is to have one thread receiving data on a socket and another thread sending data on the same socket. Having multiple threads receiving data from a socket is usually fine for UDP socket, but doesn't make much sense for TCP sockets most of the time. There is a warning in the documentation for WSARecv:

WSARecv should not be called on the same socket simultaneously from different threads, because it can result in an unpredictable buffer order.

But this usually isn't of any concern if you are using UDP and the protocol is stateless.

Also note that the WSAEINPROGRESS error code mainly applies to Winsock 1.1:

WSAEINPROGRESS: A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

And the description of WSAEINPROGRESS further states:

Operation now in progress.

A blocking operation is currently executing. Windows Sockets only allows a single blocking operation—per- task or thread—to be outstanding, and if any other function call is made (whether or not it references that or any other socket) the function fails with the WSAEINPROGRESS error.

Note that this talks about a single blocking operation per-task or thread.

Furthermore there is an additional warning in the documentation for WSARecv:

Issuing another blocking Winsock call inside an APC that interrupted an ongoing blocking Winsock call on the same thread will lead to undefined behavior, and must never be attempted by Winsock clients.

But apart from those warnings you should be fine.

Update: to add some external references: alt.winsock.programming: Is socket thread-safe? and Winsock Programmer’s FAQ: Is Winsock thread-safe?

like image 52
cmeerw Avatar answered Nov 13 '22 14:11

cmeerw


Winsock allows only one blocking IO call on a socket. More than one blocking call from different thread would end up with "WSAEINPROGRESS" error. http://msdn.microsoft.com/en-us/library/windows/desktop/ms740668%28v=vs.85%29.aspx#WSAEINPROGRESS.

If you want to make concurrent IO request you could try using asynchronous IO or overlapped IO (in windows parlance). But I guess you would want concurrent processing of data more than concurrent reading data. In which case you could have one thread issuing IO requests and others for processing.

like image 24
nanda Avatar answered Nov 13 '22 15:11

nanda