C++11——多线程编程16 如何停止或终止线程?

在本文中,我们将讨论如何在 C++11 中停止或终止线程。

C++11 没有提供停止正在运行的线程的直接方法,这是因为该线程可能有一些资源在退出前释放或关闭,即

  • 如果一个线程获得了一个锁,我们突然杀死了那个线程,那么谁来释放那个锁呢?
  • 如果一个线程打开了一个文件来写入文本,而我们停止了该线程,那么谁会关闭该文件呢?
  • 如果线程已经在堆上分配了内存并且在它可以删除该内存之前,我们会停止该线程。那么谁来防止内存泄漏。

因此没有直接关闭线程的函数。但是我们可以通知线程退出,我们可以以这样一种方式实现 out 线程,即在一段时间后或在某些检查点后,它应该检查是否要求我退出。如果是,那么它应该通过释放所有资源优雅地退出。

使用 std::future<> 停止线程

我们可以将std::future<void>对象传递给线程,当未来的值可用时,线程应该退出。因为,我们只想给线程发信号,而不是在该信号中实际传递任何值,所以我们可以使用 void 类型的未来对象。

让我们在 main 函数中创建一个 void 类型的 promise 对象,即

// 创建一个 std::promise 对象
std::promise < void > exitSignal;

现在,从主函数中的这个承诺中获取关联的未来对象,即

//获取与promise关联的std::future对象
std::future < void > futureObj = exitSignal.get_future () ;

现在在创建线程的主函数中,将未来对象传递给线程函数,即

// 启动线程并通过引用移动 lambda 函数中的未来对象
std::thread th ( &threadFunction, std:: move ( futureObj )) ;

在线程内部,我们正在做一些工作并继续检查线程是否已被请求退出,即未来的值是否可用。

void threadFunction(std::future<void> futureObj)
{
    std::cout << "Thread Start" << std::endl;
    while (futureObj.wait_for(std::chrono::milliseconds(1)) == std::future_status::timeout)
    {
        std::cout << "Doing Some Work" << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
    std::cout << "Thread End" << std::endl;
}

一旦我们从 main 函数中设置了 promise 对象的值,未来对象中的值将在线程函数中可用,即

//设置promise中的值
exitSignal.set_value();
#include <thread>
#include <iostream>
#include <assert.h>
#include <chrono>
#include <future>
void threadFunction(std::future<void> futureObj)
{
    std::cout << "Thread Start" << std::endl;
    while (futureObj.wait_for(std::chrono::milliseconds(1)) == std::future_status::timeout)
    {
        std::cout << "Doing Some Work" << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
    std::cout << "Thread End" << std::endl;
}
int main()
{
    // 创建一个 std::promise 对象
    std::promise<void> exitSignal;
    //获取与promise关联的std::future 对象
    std::future<void> futureObj = exitSignal.get_future();
    // 启动线程并且通过引用移动lambda函数中的未来对象
    std::thread th(&threadFunction, std::move(futureObj));
    //等待10秒
    std::this_thread::sleep_for(std::chrono::seconds(10));
    std::cout << "Asking Thread to Stop" << std::endl;
    //设置promise中的值
    exitSignal.set_value();
    //等待线程加入
    th.join();
    std::cout << "Exiting Main Function" << std::endl;
    return 0;
}
Thread Start
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Asking Thread to Stop
Thread End
Exiting Main Function