如何安全地停止标准线程
How to stop std thread safely?
我正在开发一个聊天服务器,我有一个问题。
如何安全地停止std::thread
?
这是非常容易的问题,就像这样。
thread t(&func);
t.join();
但是,如果 func 具有无限循环,则 join 不起作用。
这是我的消息来源。
void CServerSocket::AcceptRun(boost::asio::io_service &iosrv)
{
while (true)
{
auto sock = std::make_shared<boost::asio::ip::tcp::socket>(iosrv);
m_Acceptor->accept(*sock);
m_SocketList.push_back(std::make_shared<CConnectionSocket>(this, sock));
}
}
和
CServerSocket::~CServerSocket()
{
CLogManager::WriteLog("Stopping Server...");
m_Acceptor->close();
m_Acceptor.reset();
// m_AcceptThread.detach(); This is right?
CLogManager::WriteLog("Server Stoped!");
}
我很纳闷。请帮助我。谢谢。
您可以将合适的上下文传递给线程,该线程可以包含一个指示是否该停止的标志。旗帜可能是std::atomic<bool>
.显然,您还需要设置通信以不无限期地等待数据,以便您有机会偶尔检查标志。
我相当确定当您关闭接受器时,accept
会干净地退出,引发异常。您应该捕获异常,以便线程正常退出:
void CServerSocket::AcceptRun(boost::asio::io_service &iosrv)
try {
// your loop here, unchanged
} catch (std::exception const & ex) {
// perhaps log the message, ex.what()
}
然后在关闭接受器后但在销毁它之前加入线程:
CServerSocket::~CServerSocket()
{
CLogManager::WriteLog("Stopping Server...");
m_Acceptor->close();
m_AcceptThread.join();
CLogManager::WriteLog("Server Stopped!");
// No need to do anything else with m_Acceptor, assuming it's a smart pointer
}
就个人而言,我会使用异步操作,除非有令人信服的理由使用多个线程。单个线程更容易处理。
安全停止线程如何安全地停止 std::thread?
意味着您告诉线程函数停止处理(通过 std::thread
外部的机制),然后等待线程停止。
@DietmarKuhl的响应会告诉您如何执行此操作。关于阻止访问,您必须在套接字/接受器上设置一个选项,使其在超时时过期。当接受调用返回时,您要么中断循环(如果循环条件为 false),要么再次调用accept
,并显示新的超时。
您的超时值将是一个折衷方案:小的超时将更加计算密集(保持 CPU 繁忙),同时为您提供一个响应非常灵敏的线程函数(当您停止线程时不会阻塞太多)。
相关文章:
- 如果不包含 pthread,为什么 GCC 的线程标准库实现会抛出异常?
- 标准 cpp 数据结构和线程互斥锁?
- 标准::p set_value和线程安全
- C++ 线程时出错,标准::调用:
- C++ 杀死一个标准::线程
- 什么时候标准::线程::连接会因no_such_process而失败
- 将线程之间的标准输入/输出重定向
- 组合来自多个线程的数据的标准方法?
- 可以在构造函数初始值设定项列表中使用标准::线程
- 包装标准::线程调用函数
- 标准::atomic_应该如何...<std::shared_ptr>用于线程安全类的复制和移动操作?
- 是否使用符合标准的线程池进行 std::async 的 Visual C++ 实现
- 为什么Win API线程执行函数,而标准线程则没有
- 是否可以使用标准的C 线程而不是FLTK超时来更新窗口
- win32 标准::线程泄漏内存
- 标准::线程::id的要求.可以雾化吗?
- Visual Studio 2013标准::线程
- 正在终止自定义标准::线程池
- 标准::线程问题
- 标准::线程处的分段错误