在另一个线程

时间:2015-09-15 12:50:56

标签: c++ multithreading sockets tcp

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

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

当我使用UDP套接字时,我曾经通过从我的loopback接口在该端口上发送数据包来解决此问题,因此触发从recvfrom返回。但是,这非常不优雅,无法在TCP套接字上完成。

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

所以我想知道是否有某种方法可以在socket EAGAIN调用上触发read,这与我在超时时会得到的方式不同,所以在我的主线程上我可以在我的套接字描述符上调用一些force_return,另一个线程上的read调用会返回吗?

1 个答案:

答案 0 :(得分:3)

我通常通过在阅读主题中创建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);