如何停止包含 while(1) 的线程
Posted
技术标签:
【中文标题】如何停止包含 while(1) 的线程【英文标题】:How to stop a thread containing a while(1) 【发布时间】:2014-06-26 14:00:38 【问题描述】:我在我的班级MainWindow
中创建了一个启动server
的线程,当我关闭这个MainWindow
时,我需要停止该服务器,但我不能因为该服务器在while(true) loop
中运行。所以我看到的唯一可能就是杀死包含服务器的线程。
但这仍然不可能,因为我使用了#include <thread>
和C++11
。
我的解决方案是将boolean
传递给我的服务器,并执行循环,而这个布尔值是真的。但是当我的布尔值变为假时,我无法退出循环,因为我的服务器等待接收在完成循环之前没有出现的帧。
这是我的代码:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
ui->setupUi(this);
//Some initialisation
...
// Constructs the new thread and runs it. Does not block execution.
m_t1 = std::thread(lancerServeur);
MainWindow::~MainWindow()
delete ui;
m_t1.join();
void MainWindow::lancerServeur()
serveur s;
while(true)
s.receiveDataUDP();//Wait for a frame
那么,有没有办法在 C++11 中杀死我的线程,或者你有没有办法停止我的服务器?
谢谢。
【问题讨论】:
你不能,不是以安全或便携的方式。您可以让循环检查一些变量(可能是condition variable)并在设置时退出,而不是无限循环。 不是标准方式,不是。 C++11 断言线程需要相互协作;所以主线程需要通知子线程退出。我记得在他们将其添加到规范中时读到了这一点,它与整个程序的稳定性有关。如果线程从外部终止,它可能会使事物处于不确定状态。 @JoachimPileborg 我不能因为我的服务器等待一帧,然后暂停我的线程。 您需要修改s.receiveDataUDP();
,使其不会阻塞或使用事件。
@JohnnyMopp 我要等一帧,不等怎么办。
【参考方案1】:
如果它是一个 UDP 服务器,并且您想解除对它的阻止,以便它读取某个“停止”布尔值为真,请设置该布尔值并在本地堆栈上向其发送一条 UDP 消息,从而解除对它的阻止。
【讨论】:
【参考方案2】:您需要有一个主线程将发出信号的事件。然后您的线程等待该事件和帧的接收。当等待返回时,您检查导致等待结束的条件。如果接收到帧,则处理该帧并再次等待。如果是线程结束事件,则退出线程。
我不太了解新的标准线程库,还不能建议如何使用它们。使用 Windows 原生 API,您将使用 WaitForMultipleObjects()
。
【讨论】:
【参考方案3】:您可以创建一个指向线程对象的指针,然后在析构函数中删除该对象。
换句话说:
m_t1 = new std::thread(lancerServeur);
然后在你的析构函数中:
m_t1->detach();
delete m_t1;
当然还有将 memnber 变量改为指针:
std::thread* m_t1;
或您选择的任何其他指针。
编辑:您还必须在析构函数中调用“m_t1->detach()”,以确保线程在销毁时不可加入。在您提供的代码示例中,情况并非如此。
【讨论】:
是的,你是对的。线程需要分离然后销毁。我最初误读了 std::terminate() 的功能。我已经编辑了我的答案。 我认为 OP 的问题在于停止线程。在销毁std::thread
对象之前将其分离将使线程继续运行。
在这种情况下,在堆上分配 std::thread
如何完成任何事情?
@ComicSansMS:可以随时删除对象/线程
可以在需要时删除对象/线程 - 这根本没有解决最初的问题。以上是关于如何停止包含 while(1) 的线程的主要内容,如果未能解决你的问题,请参考以下文章