-
Notifications
You must be signed in to change notification settings - Fork 0
/
test.cpp
131 lines (119 loc) · 3.18 KB
/
test.cpp
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
#include <iostream>
#include<thread>
#include<chrono>
#include <asio/asio.hpp>
namespace asio {
class io_context;
}
const int WORK_THREAD_COUNT = 8;
asio::io_context main_thread(1);
asio::io_context work_threads(WORK_THREAD_COUNT);
asio::signal_set signals(main_thread, SIGINT, SIGTERM);
//必须定义一线程全局变量g_current_thread,并在每个线程创建时赋值为对应的io_context指针
thread_local asio::io_context* g_current_thread = &main_thread;
#ifdef WIN32
static BOOL WINAPI handleWin32Console(DWORD event)
{
switch (event)
{
case CTRL_CLOSE_EVENT:
case CTRL_C_EVENT:
{
printf("handle end\n");
main_thread.stop();
work_threads.stop();
}
return TRUE;
}
return FALSE;
}
#endif
void start()
{
for (int i = 0; i < WORK_THREAD_COUNT; ++i)
{
std::thread t([] {
std::cout << "work_thread=" << std::this_thread::get_id() << std::endl;
g_current_thread = &work_threads;
asio::io_context::work work(work_threads);
work_threads.run();
});
t.detach();
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
signals.async_wait([&](asio::error_code p1, auto p2) {
auto s = p1.message();
std::cout << s << std::endl;
main_thread.stop();
work_threads.stop();
});
#ifdef WIN32
if (!SetConsoleCtrlHandler(handleWin32Console, TRUE))
{
fprintf(stderr, "error setting event handler.\n");
}
#endif
}
#include "Task.hpp"
using namespace nicehero;
template<asio::io_context& execute = work_threads, asio::io_context& return_context = main_thread>
Task<int, execute, return_context> coro_add(int x, int y)
{
std::cout << "do coro_add in thread_id=" << std::this_thread::get_id() << std::endl;
int r = x + y;
co_return r;
}
typedef Task<bool,main_thread> MyTask;
int main(int argc, char* argv[])
{
#if defined(_DEBUG)
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
try
{
std::cout << "main_thread=" << std::this_thread::get_id() << std::endl;
start();
g_current_thread = &main_thread;
//创建一个主线程任务f (不需post,协程开始后会自动往相应的线程post出去)
auto f = []()->MyTask {
//-------主线程开始------
std::cout << "step1: now thread_id=" << std::this_thread::get_id() << std::endl;
//切换到工作线程执行coro_add
int x = co_await coro_add<work_threads, work_threads>(1, 2);
//返回后还处于此线程
std::cout << "step2: now thread_id=" << std::this_thread::get_id() << std::endl;
//切换到工作线程执行coro_add,完成后返回主线程 (使用coro_add的默认模板参数)
x += co_await coro_add(3, 4);
//-------回主线程结束------
std::cout << "step3: now thread_id=" << std::this_thread::get_id() << ",x=" << x << std::endl;
co_return true;
};
//执行协程任务f
f();
//如果任务中没有co_await,co_return,Task也可以作为一个普通函数使用
main_thread.post([]()->MyTask {
return true;
});
// asio::io_context::work work(main_thread);
main_thread.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
/*
co_spawn(main_thread, listener(), asio::detached);
asio::awaitable<int> asio_add(int x, int y)
{
int r = x + y + 100;
co_return r;
}
asio::awaitable<int> listener()
{
auto x = asio_add(3, 3);
return co_await std::move(x);
}
*/