像javaScript这样的协程函数,一看就知道怎么用:
xxx(){
return new Promise((resolve)=> {
resolve(1);
});
}
xxx.then(res=>{
console.log(res);
});
但CPP的协程相对就要复杂一些,而且相关教程一般也只讲原理不谈实现(虽然逻辑说得很清楚,就是用不了)。
这里也简单说一下协程到底是什么,首先一个线程里面的程序是从上往下运行,如果中途遇到一个很耗时的计算,也一定是计算完了之后,才继续往下执行。为了解决这个问题C++与java都可以通过新开一个线程来解决,但每开辟一个线程都是要消耗CPU资源的,所以开多了反而会导致计算机卡顿。对于客户端虽然影响不大,但服务器每秒处理几万条用户请求,难道开几万个线程嘛,不现实(而且线程可以共享资源多人开发的时候会随便加锁,加完之后可能还会导致死锁等问题)。为了解决这些问题我们就需要用到协程,协程的工作原理就是可以暂停耗时的任务,先去把不耗时的任务完成,再去执行耗时的任务。
简单点说协程就是可以暂停任务,闲下来之后再让它运行(简单吧),还可以用别的线程来运行暂停下来的任务。
来一个简单的实例(注意:C++20才有协程库):
#include
#include //sleep
#include //协程库
//生成器
class X1{
public:
X1(X1 &&other)noexcept:h_(other.h_){
other.h_ = nullptr;
}
~X1(){
if(h_){h_.destroy();}
}
bool next(){
if(h_){
h_.resume();
return !h_.done();
}
return false;
}
struct promise_type{
//内存分配失败时
static X1 get_return_object_on_allocation_failure(){
return X1{nullptr};
}
//初始化,在协程开始执行时创建返回对象
X1 get_return_object(){
return X1{ std::coroutine_handle::from_promise(*this) };
}
//被运行时,判断初始化后是否挂起,返回awaiter类型
std::suspend_always initial_suspend(){
return {};
}
//执行完毕时,判断完毕后是否挂起,返回awaiter类型
std::suspend_always final_suspend() noexcept{
return {};
}
//处理协程函数内部抛出的错误
void unhandled_exception(){
std::terminate();
}
//协程无co_return时运行(二选一) co_return;
void return_void(){}
//协程有co_return时运行(二选一) co_return 1;
//void return_value(int a){}
//协程执行co_yield时被运行 co_yield a;
std::suspend_always yield_value(void (* cF)()){
cF();
return {};
}
};
private:
std::coroutine_handle h_;
X1(std::coroutine_handle h):h_(h){}
};
X1 aF(void (* cF)()){
co_yield cF; //协程中断,并获取值
}
int main() {
//在这里会执行X1的initial_suspend()暂停并返回了一个X1
X1 a = aF([](){
sleep(5); //假装很耗时
std::cout<<123<