使用多线程进行套接字编程时,
如果线程在Accept Function上被阻止,
主线程正在尝试关闭进程,
如何安全地中断接受函数以便pthread_join?
我对如何通过连接本身到自己的端口来实现这一点的模糊记忆,以便打破接受函数。
任何解决方案都会感激不尽。
干杯
答案 0 :(得分:2)
一些选择:
a)使用非阻塞
b)使用AcceptEx()等待额外的信号,(Windows)
c)从另一个线程关闭侦听套接字,使Accept()返回错误/异常。
d)从另一个线程打开临时本地连接,使Accept()返回临时连接
答案 1 :(得分:1)
除非有什么可以接受的,否则使用accept()
的典型方法是不!这样做的方法是poll()
相应的套接字在循环中具有适当的超时。循环检查是否要退出,因为设置了适当的同步标志。
另一种方法是例如使用pthread_kill()
向被阻止的线程发送信号。这将通过适当的错误指示退出阻止的accept()
。同样,下一步是检查一些标志以查看该线程是否要退出。不过,我的偏好是第一种方法。
答案 2 :(得分:1)
根据您的系统,如果可用,我会使用select
函数等待服务器套接字读取,指示套接字正在尝试连接。等待连接的时间量可以设置/调整为每次等待客户端连接的时间(无穷大,秒数,到0,只检查并返回)。需要检查返回状态以查看是否达到了时间限制(没有套接字尝试连接),或者是否有某些东西等待服务(您的服务器套接字指示有一个客户端想要连接)。然后,您可以根据返回的状态执行accept
,知道有一个要连接的套接字。
答案 3 :(得分:1)
如果可用,我会在循环中使用带有超时的选择功能来实现此功能。
格伦建议
具有超时值的select函数将等待套接字连接一段时间。如果套接字尝试连接,则可以在此期间接受。通过使用超时循环此选择,可以检查新连接,直到满足中断条件。
以下是一个例子:
std::atomic<bool> stopThread;
void theThread ( std::atomic<bool> & quit )
{
struct timeval tv;
int activity;
...
while(!quit)
{
// reset the time value for select timeout
tv.tv_sec = 0;
tv.tv_usec = 1000000;
...
//wait for an activity on one of the sockets
activity = select( max_sd + 1 , &readfds , NULL , NULL , &tv);
if ((activity < 0) && (errno!=EINTR))
{
printf("select error");
}
if (FD_ISSET(master_socket, &readfds))
{
if ((new_socket = accept(master_socket, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
...
}
}
int main(int argc, char** argv)
{
...
stopThread = false;
std::thread foo(theThread, std::ref(stopThread));
...
stopThread = true;
foo.join();
return 0;
}
更完整的选择&#39;选择&#39; http://www.binarytides.com
我对C ++很陌生,所以我确信我的代码和答案都可以改进。
答案 4 :(得分:0)
听起来你正在寻找的是:你设置一个侦听/接受套接字已知的特殊标志变量,然后让主线程打开与侦听/接受套接字的连接。侦听/接受套接字/线程必须在每次接受连接时检查标志,以便知道何时关闭。
答案 5 :(得分:-2)
通常,如果要进行多线程网络连接,则在建立连接(或准备进行连接)后,您将生成一个线程。如果您想降低开销,那么线程池就不会太难实现。