Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
102 changes: 102 additions & 0 deletions libgo/libgohelper.h
Original file line number Diff line number Diff line change
@@ -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<void()> func):func(func){};
RunB(){};
std::function<void()> 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<ScheHandler> instance;
static std::once_flag once;
call_once(once, [&]() {
instance.reset(new ScheHandler());
});
return instance.get();
};


inline void Finish(std::vector<std::function<void()>> &list) {
std::atomic_int c {0};
c+=list.size();
co_chan<RunB> ch_0(list.size());

for(auto item : list) {
ch_0 << RunB(item);
}

for(int i = 0;i<list.size();i++){
go co_scheduler(sched)[&]{
RunB s1;
ch_0>>s1;
s1.func();
c--;
};
}
while (c) {
usleep(1000);
}
};

inline void UnsafeGo(std::function<void()>fn){
go co_scheduler(sched)[&]{
fn();
};
};

template <typename source,typename result,typename func>
inline void Mapreduce(const std::vector<source> &list,std::vector<result> &outList,func myfunc,void* handler)
{
using namespace std::placeholders;
std::atomic_int c {0};
c+=list.size();

co_chan<source> ch_0(list.size());

co_mutex cm;
std::map<source,result> filter;

for(auto item : list) {
ch_0 << item;
}
for(int i = 0;i<list.size();i++){
go co_scheduler(sched) [&]{
source s1;
ch_0>>s1;
result r1;
myfunc(handler,s1,r1);
{
std::lock_guard<co_mutex> 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
80 changes: 80 additions & 0 deletions tutorial/sample16_helper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/************************************************
* libgo sample16 libgohelper
*************************************************/
#include "libgohelper.h"
#include "win_exit.h"
#include <stdio.h>
#include <thread>


int main()
{
//----------------------------------
// libgohelper 提供两个能解决很多并发问题的封装,其以单例方法来提供给应用程序使用
// inline void Finish(std::vector<std::function<void()>> &list)
// 同步等待所有协程结束,接入方法同 go语法

int a0 = 0;
int a1 = 0;
int a2 = 0;
int a3 = 0;
int a4 = 0;
vector<std::function<void()>> 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::function<void()>fn)
// 单例直接调用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 <typename source,typename result,typename func>
//inline void Mapreduce(const vector<source> &list,vector<result> &outList,func myfunc,void* handler)
// 1.定义要查询的列表,此时参数类型为uint32_t
// vector<int> list;
// 2.定义要返回的列表,参数类型为uint32
// vector<int> 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<int> list = {2,2,3,4,5,6,7};
vector<int> 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");
}