一 前提,thread返回值的写法
在之前的代码中,我们并没有讨论 子线程的返回值问题。
这一章就考虑这个问题怎么处理。
下面我们先按照之前的写法,我们需要返回值时的可能的fix方案。
//如果线程有返回值,并且主线程要得到这个返回值,
//方案一:使用全局变量去接这个子线程的返回值。然后在main函数中取。
//如果线程有返回值,并且主线程要得到这个返回值,
//方案一:使用全局变量去接这个子线程的返回值。然后在main函数中取。
int teacher176readfuncreturnnumber = -1;
int teacher176writefuncreturnnumber = -1;
class Teacher176 {
public:
mutex mymutex;
list<int> mylist;
public:
int readfunc(string &tempstr) {
for (size_t i = 0; i < 10; i++)
{
mymutex.lock();
cout << "read func tempstr = " << tempstr << " i = " << i << " threadid = " << this_thread::get_id()<< " &tempstr = " << &tempstr << " tempstr = " << tempstr << endl;
mymutex.unlock();
}
int tempreturnvalue = 10;
teacher176readfuncreturnnumber = tempreturnvalue;
return tempreturnvalue;
}
int writefunc(double &tempdouble) {
for (size_t i = 0; i < 10; i++)
{
mymutex.lock();
cout << "write func tempdouble = " << tempdouble << " i = " << i <<" threadid = " << this_thread::get_id() << " &tempdouble = " << &tempdouble <<" tempdouble = " << tempdouble << endl;
mymutex.unlock();
}
tempdouble = tempdouble * 2;
teacher176writefuncreturnnumber = (int)tempdouble;
return (int)tempdouble;
}
};
void main() {
cout << "main thread start " << endl;
Teacher176 tea;
string name = "nihao";
double dou = 60.8;
cout << "main threadid = " << this_thread::get_id() << " &name = " << &name << " name = " << name << " dou = " << dou << " &dou = " << &dou << endl;
thread readthread(&Teacher176::readfunc,&tea, ref(name));//注意要第二个传递的 &tea,不会调用copy构造函数。注意第三个参数,如果不用ref包裹,那么传递的也是copy,即使readfunc的参数是引用,thread内部也会搞一个copy,且readfunc的参数必须是const的。
thread writethread(&Teacher176::writefunc, &tea, ref(dou));
readthread.join();
writethread.join();
cout << "teacher176readfuncreturnnumber = " << teacher176readfuncreturnnumber << " teacher176writefuncreturnnumber = " << teacher176writefuncreturnnumber << endl;
cout << "main thread end" << endl;
}
从上述代码中,虽然可以获得子线程的返回值,但是这样并不方便。
C++给考虑到这种case,提供了 async函数,返回值是 future的方案。
二 async函数模版,启动一个异步任务,返回值用 future 来接。
在标头 |
2.1 async是干啥的?
async 是一个函数模版,用来启动一个异步任务。
注意这个异步任务可能是在子线程中启动,也可能不是在子线程中启动。</