惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
Blog — PlanetScale
Blog — PlanetScale
博客园 - 【当耐特】
博客园_首页
The GitHub Blog
The GitHub Blog
月光博客
月光博客
Hugging Face - Blog
Hugging Face - Blog
有赞技术团队
有赞技术团队
博客园 - 三生石上(FineUI控件)
D
Docker
Stack Overflow Blog
Stack Overflow Blog
WordPress大学
WordPress大学
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Apple Machine Learning Research
Apple Machine Learning Research
Vercel News
Vercel News
酷 壳 – CoolShell
酷 壳 – CoolShell
雷峰网
雷峰网
小众软件
小众软件
I
InfoQ
A
About on SuperTechFans
T
The Blog of Author Tim Ferriss
S
SegmentFault 最新的问题
Microsoft Azure Blog
Microsoft Azure Blog
博客园 - Franky

博客园 - Morya

不当心升级到 redis 7.4 怎么回到 valkey8 使用 cert-manager 为 traefik 自动申请和续约 https 证书 traefik学习 k8s 1.28 安装配置 knative-serving v1.15.2 + cert-manager v1.16.1 ssh端口映射玩法 golang echo group 用法的微妙注意点 使用docker最小化部署Git CI环境 使用mailpopbox构建个人独享EmailServer Influx cli cheetsheet 通过php docker快速验证简单代码 通过k8s service代理外部服务 run gitlab-runner in k8s K8S配置traefik ingressroutes支持TLS ucloud k8s部署traefik的forward-auth 使用nginx构建限频、限速、限并发的应用保护层 macos 更改罗技k810无线键盘的映射 - Morya - 博客园 goland scope pattern 设置 Go 1.11 Module 介绍 - Morya hustOJ 添加 golang 支持
C++11 thread condition_variable mutex 综合使用
Morya · 2019-05-27 · via 博客园 - Morya
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <thread>
#include <glog/logging.h>

class Event {
public:
    Event();
    ~Event();

    bool wait(std::chrono::milliseconds millisec);
    void notify();

private:
    std::mutex m_lock;
    std::condition_variable m_cond;
};

Event::Event() {
}

Event::~Event() {
}

bool Event::wait(std::chrono::milliseconds millisec) {
    LOG(INFO)<< "before lock";
    std::unique_lock<std::mutex> l(m_lock);
    auto cv = m_cond.wait_for(l, millisec);
    if (cv == std::cv_status::no_timeout) {
        return true;
    }
    return false;
}

void Event::notify() {
    m_cond.notify_all();
}

class App {
public:
    App();
    ~App();

    bool start();
    static void threadRun(void * p);
    void run();
    void stop();
    void postExit();

private:
    Event m_event;
    std::mutex m_lock;
    std::thread * m_thread;
};

App::App() {
    m_thread = NULL;
}

App::~App() {
    m_thread = NULL;
}

bool App::start() {
    std::unique_lock<std::mutex> l(m_lock);
    if (m_thread != NULL) {
        LOG(INFO)<<"thread running";
        return false;
    }
    m_thread = new std::thread(threadRun, this);
    if (m_thread == NULL) {
        LOG(INFO)<<"create thread failed";
        return false;
    }
    LOG(INFO)<< "create thread success";
    return true;
}

void App::threadRun(void *p) {
    App * pThis = (App*) p;
    pThis->run();
}

void App::run() {
    while (!this->m_event.wait(std::chrono::milliseconds(1002))) {
        LOG(INFO)<< "sleep";
    }
}

void App::postExit() {
    delete this->m_thread;
    this->m_thread = NULL;
}

void App::stop() {
    std::unique_lock<std::mutex> l(m_lock);
    this->m_event.notify();
    this->m_thread->join();
    postExit();
}

int main(int ac, char**av) {
    google::InitGoogleLogging(av[0]);

    FLAGS_alsologtostderr = true;
    FLAGS_logtostderr = true;

    LOG(INFO)<< "app started";

    std::unique_ptr<App> p(new App);
    if (!p->start()) {
        LOG(INFO)<< "start failed";
        return 1;
    }
    for (auto i = 0; i < 3; i++) {
        std::this_thread::sleep_for(std::chrono::seconds(2));
        LOG(INFO)<<"main thread sleep";
    }
    p->stop();

    LOG(INFO)<< "main thread done";
    return 0;
}