Winsock blocking sockets, multithreading deadlock
I have tracked down a deadlock in some code of 开发者_开发知识库mine using this reproducer:
if( isClient )
{
Sender sender;
Receiver receiver;
ConnectionPtr connection = Connection::create( description );
TEST( connection->connect( ));
receiver.start();
Sleep( 100 );
sender.start();
sender.join();
}
else
{
ConnectionPtr connection = Connection::create( description );
TEST( connection->listen( ));
Sender sender;
Receiver receiver;
ConnectionPtr reader = connection->accept();
receiver.start();
Sleep( 100 );
sender.start();
receiver.join();
}
I start on the same machine a server and then a client process on 127.0.0.1:1234. Both deadlock immediately in ::recv and ::send. Sender and Receiver are separate threads executing send/recv in a loop. The sockets are blocking, BSD-style TCP sockets.
When I change the order of operations to start the Sender before the Receivers, it works.
Why?
In your example if peer1 is not reading data a peer2 will block in send after socket send buffer is full.
Usually deadlock can occur if you have some kind of a protocol and server fails to read message part while client is waiting for response.
Generally to debug this kind of problems verbose logging is introduced both on client and server sides. And when the problem occurs you can analyze logs and see what went wrong.
精彩评论