我使用std::async
创建一个线程,我希望这个新线程应该单独执行,主线程不应该等待它。但是当我调用std :: async时,会创建一个新线程,但主线程正在等待fun()
的完成。我希望主线程并行执行,而不必等待fun()
完成。我该怎么做?
#include <iostream>
#include <windows.h>
#include <future>
using namespace std;
void printid()
{
cout << "Thread id is:" << this_thread::get_id() << endl;
}
void fun(void *obj)
{
cout<<"Entry"<<endl;
printid();
Sleep(10000);
cout<<"Exit"<<endl;
}
int main()
{
cout<<"Hello"<<endl;
printid();
std::async(std::launch::async, fun, nullptr);
cout << "After call" << endl;
}
我得到了输出:
Hello
Thread id is:22832
Entry
Thread id is:13156
Exit
After call
答案 0 :(得分:4)
由std::future
返回并使用std::async
策略启动的std::launch::async
对象会阻止销毁,直到已启动的任务完成为止。
由于您没有将返回的std::future
存储在变量中,因此在语句末尾使用std::async
销毁它,因此main
无法继续,直到任务完成。
如果存储std::future
对象,其生命周期将延长至main
的末尾,您将获得所需的行为。
int main()
{
...
auto fut = std::async(std::launch::async, fun, nullptr);
...
}
答案 1 :(得分:2)
std::async(std::launch::async, fun, nullptr);
对返回的std::future
不执行任何操作,将其删除。这是一个问题,因为std::future
's destructor可能会阻塞并等待线程完成。
解决方案是坚持std::future
一段时间,并在完成其他所有操作后将其销毁。
auto locallyScopedVariable = std::async(std::launch::async, fun, nullptr);
locallyScopedVariable
将超出main
末尾的范围,然后阻止直至完成。
请注意,这仍然可能无法满足您的需求。主线程可以立即将处理器提供给新线程,并允许新线程在返回控制之前运行完成。代码可以更正,但仍会导致输出错误的版本。
答案 2 :(得分:0)
(1)在多线程程序测试中,保护共享资源(在这种情况下为cout)不使用互斥锁同时从不同的线程调用。 (2)检查主要的未来是否准备就绪,也可以暂停。
void print_id()
{
lock_guard<mutex> locker(mutex_);
cout << "Thread id is:" << this_thread::get_id() << endl;
}
void print( string str)
{
lock_guard<mutex> locker(mutex_);
cout << str << '\n';
}
bool fun(void *obj)
{
print("Entry");
printid();
Sleep(10000);
print("Exit");
return true;
}
int main()
{
print("Hello");
printid();
std::future<bool> fut = std::async(std::launch::async, fun,nullptr);
while(!fut->_Is_ready() )
{
}
cout << "After call" << endl;
}