Written a lua threadpool
工作原理
由于lua只能单线程运行,该lib要求所有lua代码在单线程,而多线程部分只能为c代码
具体用法上要求多线程部分必须用c实现
相关模块
线程池
异步函数实现框架
Now only a sleep function is provided
Usage:
function test2_threadpool()
local tp = Dll.MyTHdPool()
local n =
local function f()
n = n+
print('f ' .. n)
if(n==) then return end
tp:sleep1(, f)
end f()
tp:join()
end
C codes:
#include "stdafx.h"
#include <luabind.hpp>
#include <vector>
#include <queue>
#include <boost/thread.hpp> using namespace luabind; #include "stdafx.h" #include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread/thread.hpp> #include <deque> class ThreadPool
{
boost::asio::io_service ioService;
boost::thread_group threadpool;
boost::asio::io_service::work work;
public:
ThreadPool() :work(ioService)
{
/*
* This will start the ioService processing loop. All tasks
* assigned with ioService.post() will start executing.
*/
//boost::asio::io_service::work work(ioService); /*
* This will add threads to the thread pool. (You could just put it in a for loop)
*/
threadpool.create_thread(
boost::bind(&boost::asio::io_service::run, &ioService)
);
threadpool.create_thread(
boost::bind(&boost::asio::io_service::run, &ioService)
); }
~ThreadPool()
{ } void post(boost::function<void()> f)
{
ioService.post(f);
} void join()
{
threadpool.join_all();
}
private: }; namespace bamthread
{
typedef std::unique_ptr<boost::asio::io_service::work> asio_worker; struct ThreadPool {
ThreadPool(size_t threads) :service(), working(new asio_worker::element_type(service)) {
while (threads--)
{
auto worker = boost::bind(&boost::asio::io_service::run, &(this->service));
g.add_thread(new boost::thread(worker));
}
} template<class F>
void post(F f){
service.post(f);
} ~ThreadPool() {
working.reset(); //allow run() to exit
g.join_all();
service.stop();
} private:
boost::asio::io_service service; //< the io_service we are wrapping
asio_worker working;
boost::thread_group g; //< need to keep track of threads so we can join them
};
} void my_task()
{
Sleep();
printf("mytask");
} void test1()
{
bamthread::ThreadPool tp();
tp.post(boost::bind(my_task));
//tp.join();
} void test()
{
/*
* Create an asio::io_service and a thread_group (through pool in essence)
*/
boost::asio::io_service ioService;
boost::thread_group threadpool; /*
* This will start the ioService processing loop. All tasks
* assigned with ioService.post() will start executing.
*/
boost::asio::io_service::work work(ioService); /*
* This will add threads to the thread pool. (You could just put it in a for loop)
*/
threadpool.create_thread(
boost::bind(&boost::asio::io_service::run, &ioService)
);
threadpool.create_thread(
boost::bind(&boost::asio::io_service::run, &ioService)
); /*
* This will assign tasks to the thread pool.
* More about boost::bind: "http://www.boost.org/doc/libs/1_54_0/libs/bind/bind.html#with_functions"
*/
ioService.post(boost::bind(my_task)); /*
* This will stop the ioService processing loop. Any tasks
* you add behind this point will not execute.
*/
ioService.stop(); /*
* Will wait till all the threads in the thread pool are finished with
* their assigned tasks and 'join' them. Just assume the threads inside
* the threadpool will be destroyed by this method.
*/
threadpool.join_all();
} template <typename T>
class queue
{
private:
boost::mutex d_mutex;
boost::condition_variable d_condition;
std::deque<T> d_queue;
public:
void push(T const& value) {
{
boost::unique_lock<boost::mutex> lock(this->d_mutex);
d_queue.push_front(value);
}
this->d_condition.notify_one();
}
T pop() {
boost::unique_lock<boost::mutex> lock(this->d_mutex);
this->d_condition.wait(lock, [=]{ return !this->d_queue.empty(); });
T rc(std::move(this->d_queue.back()));
this->d_queue.pop_back();
return rc;
}
}; class MyTHdPool
{
bamthread::ThreadPool tp; boost::mutex m;
std::map<int, boost::function<void()> > f2s; // key: taskid, value: post processing //boost::thread t_; queue<int> q_;
int taskid_; public:
MyTHdPool() :tp(), taskid_(){} ~MyTHdPool(){
join();
} void Call(boost::function<void()> f1, boost::function<void()> f2)
{
int taskid = taskid_++; printf("begin call task %d\n", taskid); boost::function<void()> f = [=]() mutable {
f1(); q_.push(taskid);
printf("done task %d\n", taskid);
}; {
boost::lock_guard<boost::mutex> lock(m);
f2s[taskid] = (f2);
} tp.post(f);
printf("end post task %d\n", taskid);
} void join()
{
while (true)
{
boost::function<void()> f2;
int taskid = ;
{
{
boost::lock_guard<boost::mutex> lock(m);
if (f2s.empty())
return;
} printf("start pop a task from queue\n");
int taskid = q_.pop();
printf("got a task %d from queue\n", taskid); {
boost::lock_guard<boost::mutex> lock(m);
auto it = f2s.find(taskid);
assert(it != f2s.end());
f2 = it->second;
f2s.erase(it);
}
} printf("exec task post ftn %d\n", taskid);
f2();
}
} void sleep1(double n, object f2)
{
Call([n](){Sleep(n * ); }, [f2, this]() mutable {
f2();
});
} void sleep2(double n)
{
Call([n](){Sleep(n * ); }, [](){});
}
private: }; void callback(object o)
{
printf("before callback\n");
o();
printf("after callback\n");
} int luaopen_Dll(lua_State* L)
{ luaL_openlibs(L);
open(L); // define a module in _G["t"]
module(L, "Dll")[ class_<MyTHdPool>("MyTHdPool")
.def(constructor<>())
.def("sleep1", &MyTHdPool::sleep1)
.def("sleep2", &MyTHdPool::sleep2)
.def("join", &MyTHdPool::join), def("test1", &test1), def("callback", &callback)
]; // push _G["t"] to stack
lua_getglobal(L, "Dll"); // set _G["t"]=nil
lua_pushnil(L);
lua_setglobal(L, "Dll"); return ;
}
Written a lua threadpool的更多相关文章
- [转]LUA元表
lua元表和元方法 <lua程序设计> 13章 读书笔记 lua中每个值都有一个元表,talble和userdata可以有各自独立的元表,而其它类型的值则共享其类型所属的单一元表.lua在 ...
- Lua 笔记
lua命令: #enter shell lua #excute script file lua xxx.lua lua脚本: #!/usr/local/bin/lua 核心概念: As a exten ...
- lua function
This is the main reference for the World of Warcraft Lua Runtime. Note that these are mostly standar ...
- Lua参考手册
英文原版: http://www.lua.org/manual/5.1/ 中文版下面2个地址都有:一样的 manual.luaer.cn lua在线手册 lua参考手册Lua参考手册的中文翻译(云风翻 ...
- lua: Learning Official Doc notes
dynamically typed vars: basic types: nil, boolean, number, string, function, userdata, thread & ...
- Lua学习系列(五)
calling C functions from Lua 5.2 这篇文章也不错: http://blog.csdn.net/x356982611/article/details/26688287 h ...
- Lua的各种资源1
Libraries And Bindings LuaDirectory > LuaAddons > LibrariesAndBindings This is a list of l ...
- luaprofiler探索
什么是luaprofiler? http://luaprofiler.luaforge.net/manual.html LuaProfiler is a time profiler designed ...
- Popular Deep Learning Tools – a review
Popular Deep Learning Tools – a review Deep Learning is the hottest trend now in AI and Machine Lear ...
随机推荐
- js 数组原型
Array.isArray( Array.prototype ) // A. true // B. false // C. error // D. other 答案是A. 其实 Array.proto ...
- Servelet开发步骤和生命周期
Servelet开发步骤和生命周期 (1) 程序员开发程序,实现servelet的init和destroy接口 .重写servlet的 doGet.doPost.doPut.doDelete四个 ...
- Spring中使用Redis
普通使用Redis的方法很简单,前面的文章也有讲解,这篇文章主要就是讲解通过注解的方式实现Spring和Redis的整合.这里我们创建了3个类:1.Config 全局配置类,相当于xml配置文件2.R ...
- eclipse get set 自动添加注释
编码的时候通常要用到 JavaBean ,而在我们经常把注释写在字段上面,但生成的Get/Set方法不会生成,通过修改Eclipse源码可解决,直接上例子: /** * 员工ID */ private ...
- 弹性盒式布局flexbox(dispaly:flex)
display:flex flex-direction: row(行)/column(列)/row-reverse/column-reverse反方向 //布局 justify-content: s ...
- 数据结构算法之冒泡排序——Java语言实现
今天来谈下冒泡排序算法,这次实现由两种形式如下所示: 1.对于长度为N的数据序列,没有加标签限制,针对一开始就是有序的数据序列,仍然需要排序N-1趟来完成排序. 2.对于长度为N的数据序列,加标了签限 ...
- 汇编语言debug入门
进入windows操作系统,因为我的虚拟机用的是win7 64位,所以装了一个Dos Box 的软件来执行这些指令. 输入debug回车,这样就进入了debug模式. 1: 输入 -r 查看或者修改寄 ...
- Vue编译提示警告
There are multiple modules with names that only differ in casing.有多个模块同名仅大小写不同This can lead to unexp ...
- Element分页组件prev-text和next-text属性无效?
前情提要 /(ㄒoㄒ)/~~ 作为刚刚接触 Element 组件的人来说,看文档是第一步,但是当我想要修改分页组件里面的按钮时却遇到了问题. 文档中写到是需要给 prev-text 和 next-te ...
- 真机*Appium
一.真机连接电脑123 1.一般android手机的的USB调试模式在设置里的开发者选项中,找到开发者选项,打开USB调试 2.cmd命令→[adb devices]→回车,得到真机设备 可能存在问题 ...