只需一个hpp你就可以写出这样的协程代码
MyTask<bool> myTask()
{
//在工作线程work_thread中请求数据库,返回给主线程main_thread
auto cursor = co_await MongoFind<work_thread,main_thread>(...);
//在主线程中完成其他工作吧
while (auto* o = cursor.fetch()){
//.....
}
//send(...);
}
此hpp只需要asio和c++20,当然也可以看我的hpp代码修改出你的版本
需要gcc版本11 + 推荐使用WinLibs测试 https://winlibs.com/
测试安装方法:
cd dep
python build.py
cd ..
mkdir build
cd build
#cmake -G"your build tools" ..
#example mingw
cmake -G"MinGW Makefiles" ..
make install
cd ..
#./coro_test
coro_test.exe
#gcc编译需要添加参数 -std=c++20 -fcoroutines
#vs2017编译需要添加参数 /await
超简单的使用方法 example:
#include <asio/asio.hpp>
#include "Task.hpp"
const int WORK_THREAD_COUNT = 8; //工作线程数
asio::io_context main_thread(1);//你的主线程io_context
asio::io_context work_threads(WORK_THREAD_COUNT);//你的工作线程io_context
//必须定义一线程全局变量g_current_thread,并在每个线程创建时赋值为对应的io_context指针
thread_local asio::io_context* g_current_thread = &main_thread;
using namespace nicehero;
//开始创建一个可以co_await的协程吧
//execute 为你执行时希望的线程,return_context 为你返回后回到的线程
template<asio::io_context& execute, asio::io_context& return_context>
Task<int, execute, return_context> coro_add(int x, int y)//一个返回int的模板协程
{
//在你希望的线程中执行任务吧
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()
{
g_current_thread = &main_thread;
//创建工作线程并给g_current_thread赋值
for (int i = 0; i < WORK_THREAD_COUNT; ++i)
{
std::thread t([] {
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));
}
//do 一些初始化逻辑
//创建一个主线程任务 (不需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的默认模板参数)
int y = co_await coro_add(3, 4);
//-------回到主线程------
std::cout << "step3: now thread_id=" << std::this_thread::get_id() << std::endl;
co_return true;
};
//执行协程任务
f();
//如果任务中没有co_await,co_return,Task也可以作为一个普通函数使用
main_thread.post([]()->MyTask {
return true;
});
main_thread.run();//
return 0;
}
//这是错误的!
Task<...> a(...){
...
co_return ...
}
Task<...> b(...){
...
auto v = co_await a(...);
...
co_return ...
}
Task<...> c(...){
...
auto v = co_await b(...);
...
co_return ...
}