如何打破C ++接受功能?

时间:2012-09-24 12:32:29

标签: c++ sockets

使用多线程进行套接字编程时,

如果线程在Accept Function上被阻止,

主线程正在尝试关闭进程,

如何安全地中断接受函数以便pthread_join?

我对如何通过连接本身到自己的端口来实现这一点的模糊记忆,以便打破接受函数。

任何解决方案都会感激不尽。

干杯

6 个答案:

答案 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)

通常,如果要进行多线程网络连接,则在建立连接(或准备进行连接)后,您将生成一个线程。如果您想降低开销,那么线程池就不会太难实现。