7. StopToken
使用下述功能需要包含头文件 coke/stop_token.h。
coke::StopToken¶
coke::StopToken提供了一种机制,用于请求其他协程停止执行,并等待其执行完成。
成员函数¶
-
构造函数/析构函数
创建一个
StopToken,参数cnt表示当该对象恰好被set_finished这些次数后,会处于完成状态。该类型不可移动,不可复制。explicit StopToken(std::size_t cnt = 1) noexcept; StopToken(const StopToken &) = delete; StopToken &operator= (const StopToken &) = delete; ~StopToken(); -
重置状态
重置内部状态,以便为下一次使用做准备,在调用前确保前一个过程已正常结束。
void reset(std::size_t cnt) noexcept; -
请求停止
请求与此
StopToken关联的协程停止运行。调用后,stop_requested()将返回true,通过wait_stop_for等待的协程将被唤醒。void request_stop(); -
检查是否已经请求停止
bool stop_requested() const noexcept; -
设置一次完成事件
将内部计数减少一次,当计数达到零时,唤醒等待在
wait_finish和wait_finish_for的协程。void set_finished(); -
检查内部计数是否已经达到零
bool finished() const; -
等待完成
等待直到内部计数达到零。协程返回
bool类型,若等待成功返回true,失败返回false。coke::Task<bool> wait_finish(); -
等待完成或超时
等待直到内部计数达到零或超时。协程返回
bool类型,若等待成功返回true,超时或失败返回false。coke::Task<bool> wait_finish_for(coke::NanoSec nsec); -
等待request_stop被调用或超时
等待直到请求停止或超时。协程返回
bool类型,若等待成功返回true,超时或失败返回false。coke::Task<bool> wait_stop_for(coke::NanoSec nsec);
示例¶
#include <iostream>
#include <chrono>
#include "coke/stop_token.h"
#include "coke/sleep.h"
#include "coke/wait.h"
using namespace std::chrono_literals;
coke::Task<> worker(coke::StopToken &st) {
coke::StopToken::FinishGuard guard(&st);
// 每次循环时检查是否被要求停止
while (!st.stop_requested()) {
bool need_stop = co_await st.wait_stop_for(100ms);
if (need_stop)
break;
std::cout << "work once" << std::endl;
}
std::cout << "worker exit" << std::endl;
}
coke::Task<> stop_token() {
coke::StopToken st;
coke::detach(worker(st));
co_await coke::sleep(410ms);
// 要求worker协程停止
std::cout << "request stop" << std::endl;
st.request_stop();
// 等待worker完全结束
co_await st.wait_finish();
std::cout << "wait finished" << std::endl;
}
int main() {
coke::sync_wait(stop_token());
return 0;
}
coke::StopToken::FinishGuard¶
用于管理StopToken的完成状态,确保在超出作用域时调用set_finished。
成员函数¶
-
构造函数/析构函数
使用
StopToken对象的地址构造FinishGuard对象,当FinishGuard退出作用域时自动调用StopToken::set_finished。该对象不可移动、不可复制。explicit FinishGuard(StopToken *ptr = nullptr) noexcept; FinishGuard(const FinishGuard &) = delete; FinishGuard &operator= (const FinishGuard &) = delete; ~FinishGuard(); -
重置内部状态
使用新的
StopToken地址重置内部状态,但不会对旧的StopToken调用StopToken::set_finished。void reset(StopToken *ptr) noexcept; -
释放内部状态
等价于
reset(nullptr)。void release() noexcept;