C++11 的std::thread相关解决了不同平台线程调用方式不一致的问题,配合std::function & std::bind lambda ... 定义自己的线程池很方便。新标准还有一个字面意义更直白的异步函数 std::async
#include <future>
#include <iostream>
#include <ctime>
void test_1()
{
auto future = std::async(std::launch::deferred, [](){
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << __FUNCTION__ << " " << std::this_thread::get_id() << std::endl; // std::launch::deferred same as main thread id
return 0; // std::launch::async same as test_2 lambda thread id
});
std::cout << __FUNCTION__ << " waiting..." << std::endl;
clock_t _s = clock();
std::future_status status = future.wait_for(std::chrono::seconds(10));
clock_t _m = clock();
std::cout << __FUNCTION__ << " result is " << future.get() << std::endl;
clock_t _e = clock();
std::cout << __FUNCTION__ << " Time Cost : " << (double) (_e - _s) / CLOCKS_PER_SEC << " seconds." << std::endl;
std::cout << __FUNCTION__ << " Time Cost : " << (double) (_m - _s) / CLOCKS_PER_SEC << " seconds." << std::endl;
}
void test_2()
{
auto future = std::async(std::launch::deferred, [](){
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << __FUNCTION__ << " " << std::this_thread::get_id() << std::endl; // std::launch::deferred same as main thread id
return 0; // std::launch::async same as test_1 lambda thread id
});
std::cout << __FUNCTION__ << " waiting..." << std::endl;
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
std::future_status status = future.wait_for(std::chrono::seconds(10));
std::chrono::steady_clock::time_point xy = std::chrono::steady_clock::now();
std::cout << __FUNCTION__ << " result is " << future.get() << std::endl;
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::chrono::duration<double> time_span = std::chrono::duration_cast<std::chrono::duration<double>>(end - start);
std::cout << __FUNCTION__ << " Time Cost: " << time_span.count() << " seconds." << std::endl;
std::chrono::duration<double> time_span2 = std::chrono::duration_cast<std::chrono::duration<double>>(xy - start);
std::cout << __FUNCTION__ << " Time Cost: " << time_span2.count() << " seconds." << std::endl;
std::chrono::duration<double> time_span3 = std::chrono::duration_cast<std::chrono::duration<double>>(end - xy);
std::cout << __FUNCTION__ << " Time Cost: " << time_span3.count() << " seconds." << std::endl;
}
int main()
{
std::cout << __FUNCTION__ << " " << std::this_thread::get_id() << std::endl;
test_1();
test_2();
return 0;
}
上面参考网上的测试增加了时间相关的检查
std::launch::deferred 实际并没有开启新的线程,而是在主线程里面处理的
std::launch::async 会自己开启一个新的线程,但是test_1 和 test_2 共用一个线程,导致的结果是test_2需要等test_1真正的做完了才可以开始,这样子看还是自己实现的线程池并发性会更好
时间上 deferred 得到的结果是 test_1 : 5.003/0 ; test_2 : 5.00516/2.704e-06/5.00516,并且如果把 future.get() 的行注释掉,拿到的都是接近0的结果了
async 得到的结果是 5.002/5.002 ; 5.00362/5.00321/0.00040983, 同样注释掉 future.get() 的调用不会影响时间结果
deferred 依赖 future.get() 同步触发,async是真正的线程调用,但是只有一个线程在做事情
测试环境是 vs2017 community
其他:2017的vs支持linux的调试,实际使用时在链接的linux服务器放了相同的代码,在linux上启了gdb的进程反馈到vs中去调试,调试体验还不错,只是如果用了C++11,而linux上的编译器不支持C++11标准,就没法继续了~需要注意一下两个平台上的编译环境