管理任务
在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_cast
}
设置任务的并行方式
可以通过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
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!