Winsock阻塞套接字、多线程死锁
我使用这个重现器在我的一些代码中发现了一个死锁:
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();
}
我在同一台机器上启动服务器,然后在 127.0.0.1:1234 上启动客户端进程。 ::recv 和 ::send 中都立即陷入死锁。发送方和接收方是在循环中执行发送/接收的单独线程。这些套接字是阻塞的、BSD 风格的 TCP 套接字。
当我更改操作顺序以在接收器之前启动发送器时,它可以工作。
为什么?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在您的示例中,如果对等点 1 没有读取数据,则在套接字发送缓冲区已满后,对等点 2 将阻塞发送。
如果您有某种协议并且服务器在客户端等待响应时无法读取消息部分,通常会发生死锁。
通常,为了调试此类问题,会在客户端和服务器端引入详细日志记录。当问题发生时,您可以分析日志并查看出了什么问题。
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.