STL任务库简介

管理任务

在C++ 11的thread库引入了std::async函数,通过它可以非常容易的实现类似于.net中的Task方式的并发。

voidprintf_thread_id(constcharname)

{

cout <<name<<" Thread id: "<< this_thread::get_id() << endl;

}



intmain()

{

printf_thread_id("Main Thread");

std::future<constchar
> task1 = std::async(std::launch::async,

{

printf_thread_id("task 1");

return"hello world";

});



task1.wait();

cout << task1.get() << endl;

}

可以看到:可以通过std::async函数创建并执行一个任务,返回值为一个future对象,它提供了wait函数等待任务的执行,get函数获取任务的返回值(这个函数内部会调用wait,任务未执行完成的时候会等待),和.Net中的Task非常类似。

下面是个稍微复杂点的例子:

#include

#include

#include

usingnamespacestd;



voidprintf_thread_id(constchar*name)

{

cout <<name<<" Thread id: "<< this_thread::get_id() << endl;

}



intmain()

{

printf_thread_id("Main Thread");

autobegin = chrono::system_clock::now();



autotask1 = std::async(

{

printf_thread_id("task 1");

this_thread::sleep_for(chrono::seconds(1));

return3;

});



autotask2 = std::async(

{

printf_thread_id("task 2");

this_thread::sleep_for(chrono::seconds(1));

return5;

});



task1.wait();

task2.wait();



autoend = chrono::system_clock::now();

cout <<"total value "<< task1.get() + task2.get() << endl;

cout <<"spent time "<< chrono::duration_castmilliseconds\>(end - begin).count() << endl;

}

设置任务的并行方式

可以通过stl::async函数的第一个参数控制任务的并行方式,它有如下三个取值:

  • launch::async 异步方式。这个方式下,所有任务都会新启动一个线程执行
  • launch::deferred 同步方式。 这个方式下,任务不会新启动线程,串行在创建任务的线程中执行。
  • launch::any 综合方式。 这个方式下,会复用创建任务的线程。

这个参数也可以不带(我例2中的方式就没有带),默认情况下是launch::any。

手动控制并发

前面介绍过可以通过在async函数中通过参数设置并发方式,不过这些基本上都是些自动化的手段,有的时候粗了点,需要我们手动控制。例如:100个任务,但同时最大执行5个并发。

要手动控制任务,就不能通过async函数启动任务了,必须我们自己手动创建对象,并将其放入线程中执行。示例代码如下:

#include

#include

#include


intmain()

{

std::packaged_task<int()> task({return7;});// wrap the function

std::future<int> result = task.get_future();// get a future

std::thread(std::move(task)).detach();// launch on a thread

std::cout <<"Waiting...";

result.wait();

std::cout <<"Done!\nResult is "<< result.get() <<'\n';

}

捕获异常

和.net中的处理方式一样,任务处理过程中产生的异常可以在任务外通过get函数捕捉,非常方便。

intmain()

{

autoftr = std::async(

{

throwstd::exception("Error occurs !");

});



try

{

ftr.get();

}

catch(std::exception& e)

{

std::cout << e.what() << std::endl;

}

}

需要注意的是,wait函数并不像.net中的那样会抛异常,通过wait函数是捕获不到异常的。
原文链接: https://www.cnblogs.com/TianFang/archive/2013/01/27/2878837.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/77006

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午5:45
下一篇 2023年2月9日 下午5:45

相关推荐