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() << "\n";
} 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...\n";
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的示例,我也只能照做了;)

C++并发低级接口:std::thread和std::promise的更多相关文章

  1. c++ 如何获取多线程的返回值?(std::thread ,std::async)

    //简单的 c++11 线程,简单方便,成员函数随便调用,非成员函数也一样,如需要获取返回时,请自行使用条件变量 std::thread run([&](){ //执行一些耗时的操作 retu ...

  2. C++11 并发指南------std::thread 详解

    参考: https://github.com/forhappy/Cplusplus-Concurrency-In-Practice/blob/master/zh/chapter3-Thread/Int ...

  3. C++11 并发指南二(std::thread 详解)

    上一篇博客<C++11 并发指南一(C++11 多线程初探)>中只是提到了 std::thread 的基本用法,并给出了一个最简单的例子,本文将稍微详细地介绍 std::thread 的用 ...

  4. C++11 并发指南二(std::thread 详解)(转)

    上一篇博客<C++11 并发指南一(C++11 多线程初探)>中只是提到了 std::thread 的基本用法,并给出了一个最简单的例子,本文将稍微详细地介绍 std::thread 的用 ...

  5. 【C/C++开发】C++11 并发指南二(std::thread 详解)

    上一篇博客<C++11 并发指南一(C++11 多线程初探)>中只是提到了 std::thread 的基本用法,并给出了一个最简单的例子,本文将稍微详细地介绍 std::thread 的用 ...

  6. C++11并发——多线程std::thread (一)

    https://www.cnblogs.com/haippy/p/3284540.html 与 C++11 多线程相关的头文件 C++11 新标准中引入了四个头文件来支持多线程编程,他们分别是< ...

  7. std::thread使用

    本文将从以下三个部分介绍C++11标准中的thread类,本文主要内容为: 启动新线程 等待线程与分离线程 线程唯一标识符 1.启动线程 线程再std::threada对象创建时启动.最简单的情况下, ...

  8. C++ 并发编程,std::unique_lock与std::lock_guard区别示例

    背景 平时看代码时,也会使用到std::lock_guard,但是std::unique_lock用的比较少.在看并发编程,这里总结一下.方便后续使用. std::unique_lock也可以提供自动 ...

  9. C++ std::thread概念介绍

    C++ 11新标准中,正式的为该语言引入了多线程概念.新标准提供了一个线程库thread,通过创建一个thread对象来管理C++程序中的多线程. 本文简单聊一下C++多线程相关的一些概念及threa ...

随机推荐

  1. JDBC---bai

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import ...

  2. java 多线程系列基础篇(五)之线程等待与唤醒

    1.wait(), notify(), notifyAll()等方法介绍 在Object.java中,定义了wait(), notify()和notifyAll()等接口.wait()的作用是让当前线 ...

  3. 使用matplotlib的示例:调整字体-设置刻度、坐标、colormap和colorbar等

    使用matplotlib的示例:调整字体-设置刻度.坐标.colormap和colorbar等 2013-08-09 19:04 27805人阅读 评论(1) 收藏 举报  分类: Python(71 ...

  4. leetcode590

    树的后序遍历. class Solution { public: vector<Node> Tree; void postTree(Node node) { for (auto n : n ...

  5. Tiny4412 u-boot分析(2)u-boot启动流程

    从大方面来说,u-boot的启动分成两个阶段,第一个阶段主要的职责是准备初始化的环境,主要有以下几点 ①设置异常向量表 ②把CPU的工作模式设置为SVC32模式 ③关闭中断.MMU和cache ④关闭 ...

  6. xcode编译静态库选择cpu架构

    此前编译了一个静态库,默认支持了armv7,armv7s,arm64 编译的话肯定是上面三个静态库分别编译出来,然后在把这三个合并成一个单独的库. 如果单个库的大小是10M,那编译总的库大概就30M了 ...

  7. django之admin组件

    一.面向对象复习 1.类的继承 class Base(object): def __init__(self,val): self.val = val def func(self): self.test ...

  8. 洛谷P2146 树链剖分

    题意 思路:直接树链剖分,用线段树维护即可,算是树剖的经典题目吧. 代码: #include <bits/stdc++.h> #define ls(x) (x << 1) #d ...

  9. Java C++ Socket通讯

    import java.net.*; import javax.swing.plaf.SliderUI; /** * 与c语言通信(java做client,c/c++做server,传送一个结构) * ...

  10. Linux wine

    一.简介 Wine是Wine Is Not an Emulator(Wine不是模拟器)的缩写,其实是一个转换层(或程序装入器),能够在Linux及与POSIX兼容的其他类似操作系统上运行Window ...