c++协程生命期
元<型名 T>构 承诺;
元<型名 T>
构[[未丢弃]]任务{
用 承诺类型=承诺<T>;
任务()=默认;
~任务()=默认;
T&&取结果(){
中 承诺->取结果();
}
任务(承诺<T>*承诺):承诺{承诺}{}
私:
承诺<T>*承诺=空针;
};
元<型名 T>
构 承诺{
~承诺(){输出<<"d构造器承诺";}
任务<T>取中对象()无异{中{本};}
从不挂起 初始挂起()无异{中{};}
总是挂起 止挂起()无异{中{};}
元<型名 U>
空 返回值(U&&值){
结果.元 原位<1>(前向<U>(值));
}
空 未处理异常(){
结果.元 原位<2>(当前异常());
}
极 是准备好()常 无异{中 结果.索引()!=0;}
T&&取结果(){
如(结果.索引()==2)
再抛异常(取<2>(结果));
中 移动(取<1>(结果));
}
变量<单态,T,异常针>结果;
};
任务<整>福(){
输出<<"福():将中";
协中 42;
}
整 主(){
动 t=福();
动 r=t.取结果();
断定(t==42);
中 0;
}
测试代码可输出协程返回值,但是协程泄漏了,没有析构承诺,释放协程帧时析构承诺,协程泄漏原因是什么?
因为终挂起返回的总是挂起不是永不挂起,因此不会自动释放协程帧,需要手动释放,代码中无手动释放协程帧的逻辑.那为什么不把它的返回类型设置为永不挂起呢?
如果设置为永不挂起,协程在终挂起后就自动释放了,这时,任务里面的承诺指针也失效了,外面再取协程返回值就会出错.
只要在任务的析构器中去释放协程帧就行了:
~任务(){
协程句柄<承诺类型>::从承诺(*承诺).消灭();
}//释放了
这个休息在协程挂起后休息了1秒,然后恢复,代码从co_await后继续执行,所以这个休息的协程在await_ready()返回false的时候暂停,在await_suspend时恢复.
构 休息{
极 准备好协()常 无异{
中 时长==时长.零();
}
空 挂起协(协程句柄<>协程)常{
本线程::休息(时长);
协程();
}
空 恢复协()常 无异{}
时间::毫秒 时长;
};
任务<整>休息(){
输出<<"休息():将休息";
协待 休息{时间::秒{1}};
输出<<"休息():将中";
协中 0;
}
整 主(){
动 任务=休息();
中 0;
}
如果注释掉await_suspend中恢复协程的代码coro()会怎么样?
休息中co_await那一行代码之后的代码都不会执行,因为这个协程已挂起,没有谁去恢复它.然后就析构了这个任务及协程帧.问题是可释放挂起协程吗?答案是行.
浙公网安备 33010602011771号