如何停止包含 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) 的线程的主要内容,如果未能解决你的问题,请参考以下文章

如何停止在 Java 中的阻塞读取操作中等待的线程?

如何终止或停止 C++ 中的分离线程?

如何让fscanf自动在文件读结束时候停止执行

为啥我的布尔变量在停止线程循环时应该是可变的? [复制]

Ctrl+c 不停止 Windows + python3.7 中的线程

Java-将多线程停止的两种方法