首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C+11线程thread与任务async

C++11中提供的并发元素包括:tasks, futures, threads, mutexes, condition variables, atomic objects(std::atomic 简介) and more。

线程std::thread

thread类实现了操作系统里的线程表示,负责启动和管理线程对象;成功创建一个线程后,即可被调度执行(没有strart等方法来启动);可被 joinable 的 thread 对象必须在他们销毁之前被主线程 join 或者将其设置为 detached(否则会有异常)。

void f1(int n);

void f2(int& n);

int main()

{

int n = 0;

std::thread t1; // t1 is not a thread

std::thread t2(f1, n + 1); // pass by value

std::thread t3(f2, std::ref(n)); // pass by reference

std::thread t4(std::move(t3)); // t4 is now running f2(). t3 is no longer a thread

t2.join();

t4.join(); // 一定要join或设定joinable

}

thread中主要函数:

joinable:检查线程是否可join,即对象是否标识活跃的执行线程;

get_id:返回线程的 id;

native_handle:返回底层实现定义的线程句柄;

hardware_concurrency[静态]:返回实现支持的并发线程数;

join:等待线程执行(阻塞当前线程);

detach:分离线程;

swap:交换两个 thread 对象;

命名空间std::this_thread:

yield:放弃执行,建议再次调度线程(当前线程可能会被再次调度执行,也可能是其他线程执行);

get_id:返回当前线程的线程 id;

sleep_for:使线程休眠一段时间;

sleep_until:暂停当前线程的执行直到特定的时间点;

任务std::async

async(在头文件中)异步地运行函数 f ,并返回最终将保有该函数调用结果的 std::future。 有两种标准的加载策略:

launch::async:fun必须在一个不同(非当前)线程中异步运行;

launch::deferred:fun只有在调用了future(async的返回值)的get或者wait时(wait_for与wait_until无此功效,函数继续deferred)才会执行(同步执行,get与wait的调用者被阻塞直到fun执行完);若没有调用get或wait,则fun永远不会执行。

默认时(不传递策略)为launch::async | launch::deferred:

无法预测fun是否并发运行;

无法预测fun是否运行过(若未调用get与wait,调用时可能已运行,也可能还为运行,然后开始同步运行);

若从 std::async 获得的 std::future 未被移动或绑定到引用,则在完整表达式结尾, std::future 的析构函数将阻塞直至异步计算完成(采用async策略,且为最后一个引用时,会阻塞等待ready后以析构future):

std::async(std::launch::async, []{ f(); }); // 临时量的析构函数等待 f()

std::async(std::launch::async, []{ g(); }); //f() 完成前不开始

// 如下,若默认策略恰好选择了deffered(在负载重时很可能;此问题很难被测试出来),则wait_for循环永远不会退出(状态一直为deferred)

void fAs() {

this_thread::sleep_for(1s);

}

//auto fut = std::async(fAs);

auto fut = std::async(launch::deferred, fAs);

while (fut.wait_for(100ms) != future_status::ready) {

cout // 死循环

}

cout

std::thread与std::async

线程与任务异同:

std::thread没有直接获取返回值的方法,且如果线程中抛出异常,程序会直接崩溃(terminate);

基于线程(thread)的编程需要考虑线程耗尽、超额认购(oversubscription)、加载平衡、新平台适应等问题;而基于任务(async)的编程,默认都已帮助你处理了这些问题;

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180427G0PM8500?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券