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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Coding01

iOS 逆向开发先导篇——我是这么调试开发的

今天在整理东西的时候,无意间发现一个逆向微信的功能清单,想起来原来自己曾经还学过一些 iOS 逆向工程的皮毛知识。

16830
来自专栏Coding01

我是如何利用 workflow + 印象笔记搜集文章素材的

这段时间开始试着写作,发现需要考虑的,要做的前期工作还是很多,其中最耗时的估计就是:搜集素材

21650
来自专栏一个番茄说

移动开发流水线建立以及自动化测试

工业时代流水线的发明将生产任务的效率大大提升。同样,在软件开发过程中流水线的建立也能帮助我们更好的产出、提升效率。

15720
来自专栏developerHaoz 的安卓之旅

Android 关于移动互联网寒冬和个人核心竞争力的看法

关于 Android 市场需求,其实从前年开始 Android 就处于寒冬的境地,最直观的标志就是,工作不那么好找了。因为前几年移动互联网开始流行,很多创业公司...

12620
来自专栏贺贺的前端工程师之路

React-Native 遇到的错误1. React-Native 部分组件在debug模式下打包在iOS真机上可以显示,但是release模式下打包在iOS真机上不显示2. React-Native

这段代码在release包的情况是,buttons是空的,是由于if (child.type.name === 'FlowSendButton')这是判断根本不...

19230
来自专栏科技向令说

社交还是办公?钉钉的对手是微信还是金蝶

企业移动办公领域从来没有像今天这么火爆! 4月18日,腾讯正式推出了企业微信1.0,在iOS、Android、Windows、Mac四个平台同时开放注册下载,火...

18330
来自专栏科技向令说

响铃:被带偏的智能家居,如何才能“逃出生天”

近日,中兴在京召开了智能家居战略发布会,大喊包含“单品、整合、开放”三大要素的IOC产品战略。这把响铃的注意力再次拉回到这个“看似热闹,实则不温不火”的领域。...

15920
来自专栏科技向令说

彩电行业“四国杀”:未来全行业或只剩四家企业

如今的彩电行业早已今非昔比,以制造业为主导的野蛮增长期早已过去,市场趋于饱和,增速放缓,行业进入薄利时代,再加上智能电视概念的逐步普及以及乐视、小米、PPTV等...

9220
来自专栏一个番茄说

Cordova插件开发——滑动手势解锁(iOS篇)

第一次正儿八经的参与Cordova的项目,想写下些文字,以便日后需要的时候能够帮助自己快速回忆起来,同时也希望能够帮到需要的朋友。

17710
来自专栏一个番茄说

Swift中防止ptrace依附

在移动开发中,安全是一个很重要的话题,当然安全是没有绝对的,只能说尽可能的提高安全性。在iOS的开发中,为了防止别人窥视我们的App,我们得采用一些手段来进行防...

16230

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励