diff --git a/.vscode/settings.json b/.vscode/settings.json index 069a1b50..721448e1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -66,6 +66,34 @@ "typeindex": "cpp", "typeinfo": "cpp", "random": "cpp", - "string": "cpp" + "string": "cpp", + "bit": "cpp", + "charconv": "cpp", + "compare": "cpp", + "concepts": "cpp", + "format": "cpp", + "ios": "cpp", + "iterator": "cpp", + "locale": "cpp", + "map": "cpp", + "queue": "cpp", + "set": "cpp", + "stop_token": "cpp", + "xfacet": "cpp", + "xhash": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocbuf": "cpp", + "xlocinfo": "cpp", + "xlocmes": "cpp", + "xlocmon": "cpp", + "xlocnum": "cpp", + "xloctime": "cpp", + "xmemory": "cpp", + "xstddef": "cpp", + "xstring": "cpp", + "xtr1common": "cpp", + "xtree": "cpp", + "xutility": "cpp" } } \ No newline at end of file diff --git a/libgo/libgohelper.h b/libgo/libgohelper.h new file mode 100644 index 00000000..7327658b --- /dev/null +++ b/libgo/libgohelper.h @@ -0,0 +1,102 @@ +#ifndef LIBGO_LIBGOHELPER__INCLUDED +#define LIBGO_LIBGOHELPER__INCLUDED +#pragma once +#include "coroutine.h" +namespace libgohelper { + class RunB { + public: + RunB( std::function func):func(func){}; + RunB(){}; + std::function func; + }; + + class ScheHandler { + public: + ScheHandler(uint32_t maxThreadCount_ = 0):sched(co::Scheduler::Create()){ + std::thread t2([&]{ sched->Start(0,maxThreadCount_); }); + t2.detach(); + }; + + ~ScheHandler(){ + sched->Stop(); + }; + co::Scheduler *sched; + static ScheHandler*GetInst(){ + static std::unique_ptr instance; + static std::once_flag once; + call_once(once, [&]() { + instance.reset(new ScheHandler()); + }); + return instance.get(); + }; + + + inline void Finish(std::vector> &list) { + std::atomic_int c {0}; + c+=list.size(); + co_chan ch_0(list.size()); + + for(auto item : list) { + ch_0 << RunB(item); + } + + for(int i = 0;i>s1; + s1.func(); + c--; + }; + } + while (c) { + usleep(1000); + } + }; + + inline void UnsafeGo(std::functionfn){ + go co_scheduler(sched)[&]{ + fn(); + }; + }; + + template + inline void Mapreduce(const std::vector &list,std::vector &outList,func myfunc,void* handler) + { + using namespace std::placeholders; + std::atomic_int c {0}; + c+=list.size(); + + co_chan ch_0(list.size()); + + co_mutex cm; + std::map filter; + + for(auto item : list) { + ch_0 << item; + } + for(int i = 0;i>s1; + result r1; + myfunc(handler,s1,r1); + { + std::lock_guard lock(cm); + filter[s1] = r1; + } + c--; + }; + } + while (c) { + usleep(1000); + } + for(auto item : list) { + auto it = filter.find(item); + if(it!=filter.end()){ + outList.push_back((it->second)); + } + } + } + }; +} +#endif diff --git a/tutorial/sample16_helper.cpp b/tutorial/sample16_helper.cpp new file mode 100644 index 00000000..c39ddb95 --- /dev/null +++ b/tutorial/sample16_helper.cpp @@ -0,0 +1,80 @@ +/************************************************ + * libgo sample16 libgohelper +*************************************************/ +#include "libgohelper.h" +#include "win_exit.h" +#include +#include + + +int main() +{ + //---------------------------------- + // libgohelper 提供两个能解决很多并发问题的封装,其以单例方法来提供给应用程序使用 + // inline void Finish(std::vector> &list) + // 同步等待所有协程结束,接入方法同 go语法 + + int a0 = 0; + int a1 = 0; + int a2 = 0; + int a3 = 0; + int a4 = 0; + vector> list2 = { + [&]{a0++;}, + [&]{a1++;}, + [&]{a2++;}, + [&]{a3++;}, + [&]{a4++;} + }; + libgohelper::ScheHandler::GetInst()->Finish(list2); + printf("a0=%d a1=%d a2=%d a3=%d a4=%d \n",a0,a1,a2,a3,a4); + + // inline void UnsafeGo(std::functionfn) + // 单例直接调用go关键词,接入方法同 go语法 + + int sum = 0; + libgohelper::ScheHandler::GetInst()->UnsafeGo([&]{ + for(int i = 0;i<1000;i++){sum++;} + } + ); + printf("begin sum=%d\n",sum); + WaitUntilNoTaskS(*(libgohelper::ScheHandler::GetInst()->sched)); + printf("end sum=%d\n",sum); + + + + //template + //inline void Mapreduce(const vector &list,vector &outList,func myfunc,void* handler) + // 1.定义要查询的列表,此时参数类型为uint32_t + // vector list; + // 2.定义要返回的列表,参数类型为uint32 + // vector outList; + // 3.定义回调函数 + // [&](void *p,int &i,int &j) + // a.回调函数的第一个参数是 void*p + // 该参数是为了转换步骤4的类指针 + // b.回调函数的第二,第三个参数,分别为步骤1中的参数类型 + // c.书写回调函数 + // [&](void *p,int &i,int &j){ + // j = i+1; + // } + // 此时将 void*p 显式转为步骤4的传入的指针,并调用其成员函数 + // 如果不是成员方法直接传空即可 + // 如果是成员方法 第四个参数为 对象指针 + // [&](void *p,int &i,int &j){ + // obj *tmp = (obj *)p; + // tmp->add(i,j); + // } + + + vector list = {2,2,3,4,5,6,7}; + vector result2; + libgohelper::ScheHandler::GetInst()->Mapreduce(list,result2,[&](void *p,int &i,int &j){ + j = i+1; + },(void *)NULL); + for(auto i:result2){ + printf("%d ", i); + } + printf("\n"); +} +