-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcoroutine_01.cpp
More file actions
154 lines (138 loc) · 3.73 KB
/
coroutine_01.cpp
File metadata and controls
154 lines (138 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/**
* @Author: running-code-pp 3320996652@qq.com
* @Date: 2025-10-18 16:34:22
* @LastEditors: running-code-pp 3320996652@qq.com
* @LastEditTime: 2025-10-18 17:47:25
* @FilePath: \asio-learn-code\src\coroutine\coroutine_01.cpp
* @Description: C++20协程入门示例01
* @Copyright: Copyright (c) 2025 by ${git_name}, All Rights Reserved.
*/
// 定义协程返回值类型
#include <stdio.h>
#include <coroutine>
#include <iostream>
#include <thread>
template<typename T>
struct coro_ret
{
struct promise_type;
using handle_type = std::coroutine_handle<promise_type>;
// 协程句柄
handle_type _coro_handle;
coro_ret(handle_type h) : _coro_handle(h)
{
}
coro_ret(coro_ret&& other) : _coro_handle(other._coro_handle)
{
other._coro_handle = nullptr;
return *this;
}
coro_ret(const coro_ret&) = delete;
~coro_ret()
{
// 销毁协程
if (_coro_handle)
{
_coro_handle.destroy();
}
}
// 恢复协程,返回是否结束
bool move_next()
{
_coro_handle.resume();
return _coro_handle.done();
}
// 获取返回值
T get()
{
return _coro_handle.promise()._return_value;
}
// 定义承诺对象
struct promise_type
{
// 返回值
T _return_value;
// 几个必须定义的接口
// 生成协程函数的返回对象
auto get_return_object()
{
printf("get_return_object was called\n");
return coro_ret{ handle_type::from_promise(*this) };
}
// 确定协程初始化之后的行为,返回等待体
auto initial_suspend()
{
printf("initial_suspend was called\n");
return std::suspend_always{}; // 立即挂起
}
// co_return之后调用的行为
void return_value(T value)
{
printf("return_value was called\n");
_return_value = value;
return;
}
// co_yield之后调用的行为
auto yield_value(T value)
{
printf("yield_value was called\n");
_return_value = value;
return std::suspend_always{}; // 立即挂起
}
// 协程退出时调用的行为
auto final_suspend() noexcept
{
printf("final_suspend was called\n");
return std::suspend_always{}; // 协程结束时挂起
}
void unhandled_exception()
{
std::exit(1);
}
};
};
// 定义协程函数
coro_ret<int> simple_coroutine()
{
printf("coroutine started\n");
co_await std::suspend_never{}; // 不会挂起
printf("1st suspend coroutine\n");
co_await std::suspend_always{}; // 挂起协程
printf("2nd suspend coroutine\n");
co_yield 42; // 挂起协程并返回值42
printf("3rd suspend coroutine\n");
co_yield 100; // 返回值100并结束协程
co_return 200; // 结束协程
}
int main(){
bool done = false;
auto coro_ret = simple_coroutine();
printf("coroutine %s ret =%d\n", done ? "done" : "not done", coro_ret.get());
done = coro_ret.move_next();
printf("coroutine %s ret =%d\n", done ? "done" : "not done", coro_ret.get());
done = coro_ret.move_next();
printf("coroutine %s ret =%d\n", done ? "done" : "not done", coro_ret.get());
done = coro_ret.move_next();
printf("coroutine %s ret =%d\n", done ? "done" : "not done", coro_ret.get());
done = coro_ret.move_next();
printf("coroutine %s ret =%d\n", done ? "done" : "not done", coro_ret.get());
return 0;
}
/*
运行结果:
get_return_object was called
initial_suspend was called
coroutine not done ret =0
coroutine started
1st suspend coroutine
coroutine not done ret =0
2nd suspend coroutine
yield_value was called
coroutine not done ret =42
3rd suspend coroutine
yield_value was called
coroutine not done ret =100
return_value was called
final_suspend was called
coroutine done ret =200
*/