首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Windows C++服务中阻塞两个线程

在Windows C++服务中阻塞两个线程
EN

Stack Overflow用户
提问于 2014-09-24 06:29:19
回答 2查看 418关注 0票数 2

我有一个用C++编写的Windows服务,它充当监听传入连接的TCP服务器。

我初始化了服务器套接字,并将accept代码放在一个单独的线程中。这将接受并处理传入的连接。

但是,如果服务接收到停止信号,我也需要停止这个线程。因此,我想使用CreateEvent创建一个事件对象,并等待发出信号。此等待将发生在创建接受线程的线程中。因此,当收到停止信号时,我可以使用TerminateThread函数来停止接受线程。

然而,MSDN

TerminateThread是一个危险的函数,只能在最极端的情况下使用。

我的做法是正确的吗?还有什么办法可以做到这一点呢?

EN

回答 2

Stack Overflow用户

发布于 2014-09-24 06:44:48

在Windows中,只需调用accept即可从另一个线程唤醒阻塞的closesocket调用。阻塞的accept调用将返回-1,并且您的代码有机会通过检查已经设置的其他退出条件(例如全局变量)来突破它所处的任何循环。

这也适用于close函数的Mac (可能还有BSD衍生物),但不适用于Linux。解决此问题的更通用的UNIX解决方案是这里

下面的Windows解决方案的一些pseduo代码。

代码语言:javascript
复制
SOCKET _listenSocket;
bool _needToExit = false;
HANDLE _hThread;

void MakeListenThreadExit()
{
   _needToExit = true;
   closesocket(_listenSocket);
   _listenSocket = INVALID_SOCKET;

   // wait for the thread to exit
   WaitForSingleObject(_hThread, INFINITE);       
}

DWORD __stdcall ListenThread(void* context)
{
    while (_needToExit == false)
    {            
        SOCKET client = accept(_listenSocket, (sockaddr*)&addr, &addrSize);
        if ((client == -1) || _needToExit)
        {
            break;
        } 
        ProcessClient(client);
    }    
    return 0;
}
票数 2
EN

Stack Overflow用户

发布于 2014-09-24 08:36:21

在这种情况下,不要在阻塞套接字上使用accept()。使用非阻塞套接字代替。然后,您可以在超时时使用select(),这样线程就可以定期检查终止条件。或者更好的方法是,将WSACreateEvent()WSASelectEvent()一起使用。创建两个事件对象,一个用于检测客户端连接,另一个用于检测线程终止。然后可以使用WSAWaitForMultipleEvents()同时等待两个事件。使用WSASetEvent()在需要时向终止事件发出信号,并在其他事件发出信号时调用accept()WSAAccept()WSAWaitForMultipleEvents()会告诉你该对哪个事件采取行动。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26010024

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档