C++ 多线程的错误和如何避免(11)
不要在对时间敏感的上下文中使用 .get()
先看下面的代码,
#include "stdafx.h"
#include <future>
#include <iostream>
int main()
{
std::future<int> myFuture = std::async(std::launch::async, []()
{
std::this_thread::sleep_for(std::chrono::seconds(10));
return 8;
});
// Update Loop for rendering data
while (true)
{
// Render some info on the screen
std::cout << "Rendering Data" << std::endl;
int val = myFuture.get(); // this blocks for 10 seconds
// Do some processing with Val
}
return 0;
}
示例显示主线程在等待 std::async 返回的结果,但是 while 循环将被阻塞,直到异步任务完成(在这种情况下为 10 秒)。如果将此视为在屏幕上呈现数据的循环,则可能会导致非常糟糕的用户体验。
另外还需要注意的是,它试图在没有共享状态的情况下第二次调用 .get(),这样会导致程序崩溃,因为 future 结果已经在第一次循环时检索了。
解决方案是在调用 .get() 之前检查 myFuture 是否有效,这样既不会阻塞异步作业的完成,也不会尝试轮询已经检索的值。
#include "stdafx.h"
#include <future>
#include <iostream>
int main()
{
std::future<int> myFuture = std::async(std::launch::async, []()
{
std::this_thread::sleep_for(std::chrono::seconds(10));
return 8;
});
// Update Loop for rendering data
while (true)
{
// Render some info on the screen
std::cout << "Rendering Data" << std::endl;
if (myFuture.valid())
{
int val = myFuture.get(); // this blocks for 10 seconds
// Do some processing with Val
}
}
return 0;
}

浙公网安备 33010602011771号