Written a lua threadpool

Now only a sleep function is provided

Usage:

function test2_threadpool()
    local tp = Dll.MyTHdPool()
    local n =1
    local function f()
        n = n+1
        print(‘f ‘ .. n)
        if(n==50) then return end
        tp:sleep1(0, 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 2 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(1000);
    printf("mytask");
}

void test1()
{
    bamthread::ThreadPool tp(3);
    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 2 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(3), taskid_(0){}

    ~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 = 0;
            {
                {
                    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 * 1000); }, [f2, this]() mutable {
            f2();
        });
    }

    void sleep2(double n)
    {
        Call([n](){Sleep(n * 1000); }, [](){});
    }
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 1;
}

原文地址:https://www.cnblogs.com/cutepig/p/10203967.html

时间: 2025-01-17 04:35:52

Written a lua threadpool的相关文章

lua: Learning Official Doc notes

dynamically typed vars: basic types: nil, boolean, number, string, function, userdata, thread & table. where nil has only one value, is mainly to differ from other types. absense of useful info bool: false & true. so false & nil are both make

c++对象与lua绑定

2015.1.29 wqchen. 转载请注明出处 http://www.cnblogs.com/wqchen/ 本文主要探讨c++的类对象和lua脚本的绑定使用,读者需要有一定的lua以及lua的c api接口知识:). 如果你使用过c/c++和lua混合编程,那么肯定会熟悉宿主(c/c++)与脚本(lua)之间函数的注册与调用.userdata等等方面知识.宿主对象与脚本的绑定使用,其实可以看作是userdata与注册函数的整合,只不过多了一层语法糖.下面我们一起来分析一下这层语法糖是怎样实

Lua的各种资源1

Libraries And Bindings     LuaDirectory > LuaAddons > LibrariesAndBindings This is a list of libraries implemented in Lua or implemented in another language (e.g. C) but having a Lua interface. For older libraries and bindings, see the LuaAddonsArch

luaprofiler探索

什么是luaprofiler? http://luaprofiler.luaforge.net/manual.html LuaProfiler is a time profiler designed to help finding bottlenecks on your Lua program. If you use LuaProfiler into your program, it will generate a log of all your function calls and their

Awesome Torch

Awesome Torch This blog from: A curated list of awesome Torch tutorials, projects and communities. Table of Contents Tutorials Model Zoo Recurrent Networks Convolutional Networks ETC Libraries Model related GPU related IDE related ETC Links Tutorials

git 对 Microsoft Word 进行版本控制

昨天中国高校发生了一件骇人听闻的事情,听说不少高校的校园网用户连接校园网被勒索病毒给黑了,重要文件全部被加密,必须要支付赎金才能解密,具体新闻可以参见:http://www.sohu.com/a/140236495_346360.而且还有不少是和我一样的大四毕业狗,听说因为毕业论文没有备份,结果被黑了,然后,然后就没有然后了...真的是欲哭无泪啊.看到这个消息,我想起来我的没写完的毕业论文好像也没备份,吓得我赶紧去把论文备份到onedrive上面去了.据说微软之前已经打过补丁了,只是我国广大使用

Python &amp; 机器学习入门指导

Getting started with Python & Machine Learning(阅者注:这是一篇关于机器学习的指导入门,作者大致描述了用Python来开始机器学习的优劣,以及如果用哪些Python 的package 来开始机器学习.) Machine learning is eating the world right now. Everyone and their mother are learning about machine learning models, classif

All Things Markdown

https://javachen.github.io/ 概述 特点 语法 编辑器 浏览器插件 实现版本 参考资料 概述 Markdown 是一种轻量级标记语言,创始人为约翰·格鲁伯(John Gruber)和亚伦·斯沃茨(Aaron Swartz).它允许人们"使用易读易写的纯文本格式编写文档,然后转换成有效的XHTML(或者HTML)文档".这种语言吸收了很多在电子邮件中已有的纯文本标记的特性. 特点 兼容 HTML 要在Markdown中输写HTML区块元素,比如<div&g

lua curl动态链接库编译安装

关于lua curl的资料网上并不是很多.找来找去就那么几个,所以我绝得很有必要把我的经验记下来,以防下次忘记 ---好记性不如烂笔头. 如果在网上(当然是Google)搜索挂关键字“lua curl”或“luacurl”,你搜索的头两条数据很可能是不一样.因为关于lua的curl库有两个:luacurl和Lua-cURL. 如果你打开了这个网址“http://curl.haxx.se/libcurl/lua/”,你就会看这样一段话: There are two different effort