线程池使用ASIO - 线程退出,任务不执行 [英] ThreadPool using ASIO - Threads Exit, Task not performed

查看:243
本文介绍了线程池使用ASIO - 线程退出,任务不执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写一个线程池类在C ++中使用Boost ASIO。以下是我迄今写的code:

ThreadPool类

 使用命名空间std;
    使用名字空间boost;    类ThreadPoolClass {
    私人的:        / *到的最大线程数限制为
         *此池中的实例
         * /
        诠释maxThreads;
        / *在池*线程组/
        thread_group线程池;        ASIO :: io_service对象asyncIOService;        _Init无效()
        {
            maxThreads = 0;
        }
    上市:
        ThreadPoolClass();
        ThreadPoolClass(INT maxNumThreads);
        ThreadPoolClass(常量ThreadPoolClass&安培;原稿);
        无效CreateThreadPool();
        无效RunTask(JobClass * aJob);
        虚拟〜ThreadPoolClass();    };
    ThreadPoolClass :: ThreadPoolClass(){
    _在里面();
    }ThreadPoolClass :: ThreadPoolClass(INT maxNumThreads){
    _在里面();
    maxThreads = maxNumThreads;
}无效ThreadPoolClass :: CreateThreadPool(){    ASIO :: io_service对象::工作工作(asyncIOService);    的for(int i = 0; I< maxThreads,我++){
        COUT<<推<< ENDL;
        threadPool.create_thread(BIND(安培; ASIO :: io_service对象::来看,&安培; asyncIOService));
    }
}无效ThreadPoolClass :: RunTask(JobClass * aJob){
    COUT<<RunTask<< ENDL;
    asyncIOService.post(BIND(安培; JobClass ::运行,aJob));
}ThreadPoolClass :: ThreadPoolClass(常量ThreadPoolClass&安培;原稿){
}ThreadPoolClass ::〜ThreadPoolClass(){
    COUT<<杀死你们都<< ENDL;
    asyncIOService.stop();
    threadPool.join_all();
}

作业类

 使用命名空间std;类JobClass {
私人的:
    int类型的;
    INT B:
    INT℃;上市:    JobClass(){
        //空的构造
    }    JobClass(INT VAL){
        A = VAL;
        B = VAL - 1;
        C = VAL + 1;
    }    无效的run()
    {
        COUT<<A:<< A<< ENDL;
        COUT<<B:<< B<< ENDL;
        COUT&所述;&下;C:&所述; c为C&所述;&下; ENDL;
    }};

主要

 使用命名空间std;INT主(INT ARGC,字符** argv的){    ThreadPoolClass ccThrPool(20);
    ccThrPool.CreateThreadPool();
    JobClass ccJob(10);
    COUT<< 启动......<< ENDL;
    而(1)
    {
        ccThrPool.RunTask(安培; ccJob);
    }
    返回0;
}

所以,基本上我创建20个线程,但截至目前只发布只有一个(下同)的任务必须由IOService的运行(只是为了简单起见这里得到根本原因)。以下是输出的,当我运行这个程序在GDB:

 
[新主题0xb7cd2b40(LWP 15809)]

[新主题0xb74d1b40(LWP 15810)]

[新主题0xb68ffb40(LWP 15811)]

[新主题0xb60feb40(LWP 15812)]

[新主题0xb56fdb40(LWP 15813)]

[新主题0xb4efcb40(LWP 15814)]

[新主题0xb44ffb40(LWP 15815)]

[新主题0xb3affb40(LWP 15816)]

[新主题0xb30ffb40(LWP 15817)]

[新主题0xb28feb40(LWP 15818)]

[新主题0xb20fdb40(LWP 15819)]

[新主题0xb18fcb40(LWP 15820)]

[新主题0xb10fbb40(LWP 15821)]

[新主题0xb08fab40(LWP 15822)]

[新主题0xb00f9b40(LWP 15823)]

[新主题0xaf8f8b40(LWP 15824)]

[新主题0xaf0f7b40(LWP 15825)]

[新主题0xae8f6b40(LWP 15826)]

[新主题0xae0f5b40(LWP 15827)]

[新主题0xad8f4b40(LWP 15828)]
开始...
RunTask
杀死你们都
[主题0xb4efcb40(LWP 15814)退出]
[主题0xb30ffb40(LWP 15817)退出]
[主题0xaf8f8b40(LWP 15824)退出]
[主题0xae8f6b40(LWP 15826)退出]
[主题0xae0f5b40(LWP 15827)退出]
[主题0xaf0f7b40(LWP 15825)退出]
[主题0xb56fdb40(LWP 15813)退出]
[主题0xb18fcb40(LWP 15820)退出]
[主题0xb10fbb40(LWP 15821)退出]
[主题0xb20fdb40(LWP 15819)退出]
[主题0xad8f4b40(LWP 15828)退出]
[主题0xb3affb40(LWP 15816)退出]
[主题0xb7cd2b40(LWP 15809)退出]
[主题0xb60feb40(LWP 15812)退出]
[主题0xb08fab40(LWP 15822)退出]
[主题0xb68ffb40(LWP 15811)退出]
[主题0xb74d1b40(LWP 15810)退出]
[主题0xb28feb40(LWP 15818)退出]
[主题0xb00f9b40(LWP 15823)退出]
[主题0xb44ffb40(LWP 15815)退出]
[劣质1(15808工艺)正常退出]

我有两个问题:


  1. 为什么会这样,我的线程退出,甚至当我张贴
    在循环任务?

  2. 为什么从JobClass即变量的值的a,b的输出
    和c没有得到印?


解决方案

我想这是因为你创建的CreateThreadPool方法,它是自动销毁工作对象时,超出范围 - 在这种情况下,io_service对象>没有积极工作并且不处理任务。

试着让你的线程池类的工作的实例变量,而不是当地的一个在方法。

 类ThreadPoolClass {
私人的:    thread_group线程池;    ASIO :: io_service对象asyncIOService;    性病:: auto_ptr的< ASIO :: io_service对象::工作>工作_;上市:
};ThreadPoolClass :: ThreadPoolClass(INT maxNumThreads){
    _在里面();
    maxThreads = maxNumThreads;
}无效ThreadPoolClass :: CreateThreadPool(){    work_.reset(新ASIO :: io_service对象::工作(asyncIOService));    的for(int i = 0; I< maxThreads,我++){
        COUT<<推<< ENDL;
        threadPool.create_thread(BIND(安培; ASIO :: io_service对象::来看,&安培; asyncIOService));
    }
}

I am writing a ThreadPool Class in C++ using Boost ASIO. The following is the code that I have written so far:

The ThreadPool Class

    using namespace std;
    using namespace boost;

    class ThreadPoolClass {
    private:

        /* The limit to the maximum number of threads to be
         * instantiated within this pool 
         */
        int maxThreads; 
        /* Group of threads in the Pool */
        thread_group threadPool;

        asio::io_service asyncIOService;

        void _Init()
        {
            maxThreads = 0;
        }
    public:
        ThreadPoolClass();
        ThreadPoolClass(int maxNumThreads);
        ThreadPoolClass(const ThreadPoolClass& orig);
        void CreateThreadPool();
        void RunTask(JobClass * aJob);
        virtual ~ThreadPoolClass();

    };
    ThreadPoolClass::ThreadPoolClass() {
    _Init();
    }



ThreadPoolClass::ThreadPoolClass(int maxNumThreads) {
    _Init();
    maxThreads = maxNumThreads;
}

void ThreadPoolClass::CreateThreadPool() {

    asio::io_service::work work(asyncIOService);

    for (int i = 0; i < maxThreads; i++) {
        cout<<"Pushed"<<endl;
        threadPool.create_thread(bind(&asio::io_service::run, &asyncIOService));
    }
}

void ThreadPoolClass::RunTask(JobClass * aJob) {
    cout<<"RunTask"<<endl;
    asyncIOService.post(bind(&JobClass::Run,aJob));
}

ThreadPoolClass::ThreadPoolClass(const ThreadPoolClass& orig) {
}

ThreadPoolClass::~ThreadPoolClass() {
    cout<<"Kill ye all"<<endl;
    asyncIOService.stop();
    threadPool.join_all();
}

The Job Class

using namespace std;

class JobClass {
private:
    int a;
    int b;
    int c;

public:

    JobClass() {
        //Empty Constructor
    }

    JobClass(int val) {
        a = val;
        b = val - 1;
        c = val + 1;
    }

    void Run()
    {
        cout<<"a: "<<a<<endl;
        cout<<"b: "<<b<<endl;
        cout<<"c: "<<c<<endl;
    }

};

Main

using namespace std;

int main(int argc, char** argv) {

    ThreadPoolClass ccThrPool(20);
    ccThrPool.CreateThreadPool();
    JobClass ccJob(10);
    cout << "Starting..." << endl;
    while(1)
    {
        ccThrPool.RunTask(&ccJob);
    }
    return 0;
}

So, basically I am creating 20 threads, but as of now just posting only one (same) task to be run by ioservice (just to keep things simple here and get to the root cause). The following is the output when I run this program in GDB:

Pushed
[New Thread 0xb7cd2b40 (LWP 15809)]
Pushed
[New Thread 0xb74d1b40 (LWP 15810)]
Pushed
[New Thread 0xb68ffb40 (LWP 15811)]
Pushed
[New Thread 0xb60feb40 (LWP 15812)]
Pushed
[New Thread 0xb56fdb40 (LWP 15813)]
Pushed
[New Thread 0xb4efcb40 (LWP 15814)]
Pushed
[New Thread 0xb44ffb40 (LWP 15815)]
Pushed
[New Thread 0xb3affb40 (LWP 15816)]
Pushed
[New Thread 0xb30ffb40 (LWP 15817)]
Pushed
[New Thread 0xb28feb40 (LWP 15818)]
Pushed
[New Thread 0xb20fdb40 (LWP 15819)]
Pushed
[New Thread 0xb18fcb40 (LWP 15820)]
Pushed
[New Thread 0xb10fbb40 (LWP 15821)]
Pushed
[New Thread 0xb08fab40 (LWP 15822)]
Pushed
[New Thread 0xb00f9b40 (LWP 15823)]
Pushed
[New Thread 0xaf8f8b40 (LWP 15824)]
Pushed
[New Thread 0xaf0f7b40 (LWP 15825)]
Pushed
[New Thread 0xae8f6b40 (LWP 15826)]
Pushed
[New Thread 0xae0f5b40 (LWP 15827)]
Pushed
[New Thread 0xad8f4b40 (LWP 15828)]
Starting...
RunTask
Kill ye all
[Thread 0xb4efcb40 (LWP 15814) exited]
[Thread 0xb30ffb40 (LWP 15817) exited]
[Thread 0xaf8f8b40 (LWP 15824) exited]
[Thread 0xae8f6b40 (LWP 15826) exited]
[Thread 0xae0f5b40 (LWP 15827) exited]
[Thread 0xaf0f7b40 (LWP 15825) exited]
[Thread 0xb56fdb40 (LWP 15813) exited]
[Thread 0xb18fcb40 (LWP 15820) exited]
[Thread 0xb10fbb40 (LWP 15821) exited]
[Thread 0xb20fdb40 (LWP 15819) exited]
[Thread 0xad8f4b40 (LWP 15828) exited]
[Thread 0xb3affb40 (LWP 15816) exited]
[Thread 0xb7cd2b40 (LWP 15809) exited]
[Thread 0xb60feb40 (LWP 15812) exited]
[Thread 0xb08fab40 (LWP 15822) exited]
[Thread 0xb68ffb40 (LWP 15811) exited]
[Thread 0xb74d1b40 (LWP 15810) exited]
[Thread 0xb28feb40 (LWP 15818) exited]
[Thread 0xb00f9b40 (LWP 15823) exited]
[Thread 0xb44ffb40 (LWP 15815) exited]
[Inferior 1 (process 15808) exited normally]

I have two questions:

  1. Why is it so that my threads are exiting, even when I am posting tasks in a while loop?
  2. Why is the output from JobClass i.e. the values of the variables a,b and c not getting printed?

解决方案

I think this happens because you create work object in the CreateThreadPool method, which is automatically destroyed when goes out of scope -> in this case io_service has no active work and does not process your tasks.

Try to make 'work' instance variable of your ThreadPool class, not local one in the method.

class ThreadPoolClass {
private:

    thread_group threadPool;

    asio::io_service asyncIOService;

    std::auto_ptr<asio::io_service::work> work_;

public:
};



ThreadPoolClass::ThreadPoolClass(int maxNumThreads) {
    _Init();
    maxThreads = maxNumThreads;
}

void ThreadPoolClass::CreateThreadPool() {

    work_.reset(new asio::io_service::work(asyncIOService));

    for (int i = 0; i < maxThreads; i++) {
        cout<<"Pushed"<<endl;
        threadPool.create_thread(bind(&asio::io_service::run, &asyncIOService));
    }
}

这篇关于线程池使用ASIO - 线程退出,任务不执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆