Winsock阻塞套接字、多线程死锁

发布于 2024-09-10 21:44:58 字数 771 浏览 4 评论 0原文

我使用这个重现器在我的一些代码中发现了一个死锁:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怀中猫帐中妖 2024-09-17 21:44:58

在您的示例中,如果对等点 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文