如何在一个睡眠状态的std::thread中唤醒它

如何在一个睡眠状态的std::thread中唤醒它

在本文中,我们将讨论如何在一个睡眠状态的 std::thread 中唤醒它。众所周知,当一个线程处于睡眠状态时,它不能退出。因此它使用以下命令被唤醒:

std::condition_variable

以下是实现同样功能的伪代码:

// 自定义类
struct MyClass {
  
    // 构造函数
    MyClass()
        : my_thread([this]() {
            this->thread();
        })
    {
    }
  
    // 析构函数
    ~MyClass()
    {
        {
            std::lock_guard<std::mutex> l(m_);
            stop_ = true;
        }
        c_.notify_one();
        my_thread.join();
    }
  
    // 实现线程的函数
    void thread()
    {
        while (this->wait_for(std::chrono::minutes(2)))
            SendStatusInfo(some_info);
    }
  
    // 当线程停止时返回false的函数
    template <class Duration>
    bool wait_for(Duration duration)
    {
        std::unique_lock<std::mutex> l(m_);
        return !c_.wait_for(l, duration, [this]() {
            return stop_;
        });
    }
  
    // 条件变量
    std::condition_variable c_;
    std::mutex m_;
    bool stop_ = false;
    std::thread my_thread;
};
C++

以下是另一个示例,以说明相同的方法:

std::promise/std::future

上述命令可以用作更简单的替代方法。在这种情况下,一个 Future 不易受到错误唤醒,也不需要一个 mutex 进行同步。以下是实现同样功能的伪代码:

// Promise Condition
std::promise<void> pr;
  
// 开始线程
std::thread thr{
        [fut = pr.get_future()]{
  
            // 反复迭代直到条件退出
            while (true){
                if (fut.wait_for(std::chrono::minutes(2))
                    != std::future_status::timeout) return;
}
}
}
;
  
// 准备停止
pr.set_value();
  
// 加入线程
thr.join();
C++

以下是用于说明上述概念的程序:

// C++程序,演示线程在睡眠时被唤醒
#include <bits/stdc++.h>
using namespace std;
  
std::deque<int> q;
std::mutex mu;
std::condition_variable cond;
  
// 创建线程1的函数
void function_1()
{
    // 初始化计数器变量
    int count = 10;
  
    // 执行到计数器变量为正
    while (count > 0) {
  
        // 互斥锁
        std::unique_lock<mutex> locker(mu);
  
        // 将当前的计数器变量推入到队列中
        q.push_front(count);
        locker.unlock();
        cond.notify_one();
  
        // 如果有线程在等待,则通知该线程
        std::this_thread::sleep_for(
            chrono::seconds(1));
  
        // 减小计数器变量
        count--;
    }
}
  
// 创建线程2的函数
void function_2()
{
    // 初始化一个变量以从队列中获取数据
    int data = 0;
  
    while (data != 1) {
  
        std::unique_lock<mutex> locker(mu);
  
        cond.wait(locker, []() {
            return !q.empty();
        });
  
        // 睡眠结束后虚假唤醒
        data = q.back();
        q.pop_back();
        locker.unlock();
  
        // 输出信息
        cout << "t2 got a value from"
                " t1"
             << data << '\n';
    }
}
  
// 主函数
int main()
{
    // 创建线程1
    std::thread t1(function_1);
  
    // 创建线程2
    std::thread t2(function_2);
  
    // 等待线程结束
    t1.join();
    t2.join();
  
    return 0;
}  
C++

输出结果:

如何在一个睡眠状态的std::thread中唤醒它

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册