c++ - 在另一个线程接收的套接字上触发 EAGAIN

标签 c++ multithreading sockets tcp

假设我有两个线程,主线程和一个专用于连续监听标准 TCP 套接字的线程。现在,说在某个时候我想关闭所有东西。从主线程,我想关闭监听线程正在处理的连接,然后加入线程并结束程序。

但是,这很棘手,因为我不知道如何让监听线程从对 read 的调用中返回。除非实际收到某些内容,否则该调用不会返回,原则上我可能会等待很长时间,直到另一个端点决定向我发送一些内容。

当我使用 UDP 套接字时,我曾经通过从我的环回接口(interface)在该端口上发送数据包来解决这个问题,从而触发从 recvfrom 的返回。然而,这是非常不优雅的,它不能在 TCP 套接字上完成。

我知道另一种解决方法是使用 setsockopt 设置超时:这样我可以保证调用最终会返回,但这也很不优雅,而且效率也很低,因为我可能需要等待几秒钟才能加入线程。

所以我想知道是否有某种方法可以在套接字 read 调用上触发 EAGAIN,就像我在超时时遇到的那样,所以我的主线程 我可以在我的套接字描述符上调用一些 force_return 并且在另一个线程上调用 read 会返回吗?

最佳答案

我通常通过创建 pipe() 来解决这个问题并使用 select()在阅读线程中。读取线程必须同时选择 TCP 套接字和管道的一端。每当您想关闭读取器时,设置一个标志并将一些数据写入管道的另一端。

设置:

#include <unistd.h>

int signalPipe[2];

...

pipe(signalPipe);

读者:

while(running)
{
    FD_ZERO(&fds);
    FD_SET(tcpSocket, &fds);
    FD_SET(signalPipe[0], &fds);
    select(max(tcpSocket, signalPipe[0]) + 1, &fds, NULL, NULL, NULL);
    ...
}

其他线程:

// We want to stop now.
running = false;
write(signalPipe[1], "foo", 3);

关于c++ - 在另一个线程接收的套接字上触发 EAGAIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32586593/

相关文章:

c - 未收到完整数据

c++ - 使用 gdbserver 从 clion 调试 jni 库

c++ - WinCE 上 C++ 中的一次性定时器

java - 线程安全与否?

c# - 如何在不暂停或中断程序的情况下在 C# 中多线程读取行?

c - UDP 客户端不会自动重新连接

java - 多人游戏(Java 套接字写入/读取对象)

c++ - Allegro 4.2.1,去除 bmp 背景颜色

c++ - Boost::Tuples vs Structs 返回值

c# - 如何计算/分析并行 C# 代码的百分比