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那一行代码之后的代码都不会执行,因为这个协程已挂起,没有谁去恢复它.然后就析构了这个任务协程帧.问题是可释放挂起协程吗?答案是.

posted @   zjh6  阅读(5)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示