zoukankan      html  css  js  c++  java
  • C++并发低级接口:std::thread和std::promise

    std::thread和std::promise

    相比std::async,std::thread就原始多了。thread一定会创建新线程(而不是像async那样创建的时候可能不会,后面才创建新线程(std::launch::deferred)),并且创建它的线程还必须指定以何种策略等待新线程。

    #include <iostream>
    #include <thread>
    
    void task() {
        for (int i = 0; i < 10; i++) {
            std::cout << "A";
        }
    }
    
    int main() {
        std::thread td(task);
        for (int i = 0; i < 10; i++) {
            std::cout << "B";
        }
        td.join();
        system("pause");
        return 0;
    }
    

    这里首先std::thread td(task);创建新线程异步输出"A",然后主线程输出"B",td.join()就是所谓的创建它的线程还必须指定以何种策略等待新线程,有两种策略可供选择:

    • std::thread.join() 阻塞直到子线程结束
    • std::thread.detach() 不阻塞。让它自由发挥。
      虽然std::thread.detach()可以不阻塞主线程,但是如果主线程结束那这些后台任务都会强行终止,比如你后台是下载任务,所以几乎没有直接用detach的,都是配合后面的同步机制如std::condition_variable

    这里也凸显了std::async的高级和std::thread的低级:在std::async中我们可以对它的返回值即std::future简单的调用get()实现同步等待甚至能获取任务的结果,但是std::thread就不行,要等待子线程结束或者获取子线程执行结果需要条件变量等同步机制。

    std::promise

    std::promise独树一帜,它用于线程间传递值,其中std::promise.set_value是设置值,std::promise.set_exception是设置异常,注意两者不能同时设置。std::promise.get_future则是返回一个std::future。因为我们设置了值总会获取它吧,获取的方法就是get_future(),然后再get():

    #include <iostream>
    #include <thread>
    #include <future>
    
    void task(std::promise<int>& p) {
        std::cout << "Retrieve value from another thread:" << p.get_future().get() << "
    ";
    }
    
    int main() {
        std::promise<int> p;
        std::thread td(task,std::ref(p));
        std::this_thread::sleep_for(std::chrono::seconds(3));
        std::cout << "Task in main thread accomplished...
    ";
        p.set_value(1024);
        td.join();
        system("pause");
        return 0;
    }
    

    程序先输出"Task in main thread accomplished..."再输出"Retrieve value from another thread:1024"。task线程中p.get_future().get()会阻塞当前线程直到promise已经设置值,即task线程会一直阻塞直到main线程执行
    p.set_value(1024);后才继续执行。

    多说一点,其实std::promise和std::future都是多线程状态共享的方案,这两种不存在高级低级,只有std::async和std::thread有点高级低级之分。不过《C++标准库》中这样分类,加之std::future,std::promise分别用于std::async和std::thread的示例,我也只能照做了;)

  • 相关阅读:
    显卡,显卡驱动,nvcc, cuda driver,cudatoolkit,cudnn到底是什么?
    安装cuda之后没有安装nvidia显卡驱动可能会出现ImportError: libcuda.so.1: cannot open shared object file: No such file or directory
    ubuntu安装
    老男孩Linux查看硬盘使用个情况及其挂载点
    Anaconda使用conda activate激活环境出错CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
    Linux,ubuntu设置anaconda的环境变量
    Linux 磁盘管理
    anaconda路径改变后对其中文件的修改
    Linux 文件基本属性
    川藏游记发在别处的
  • 原文地址:https://www.cnblogs.com/ysherlock/p/8970850.html
Copyright © 2011-2022 走看看