线程池使用ASIO - 线程退出,任务不执行(ThreadPool using ASIO - Th

2019-09-22 06:02发布

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

ThreadPool类

    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();
}

作业类

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;
    }

};

主要

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;
}

所以,基本上我创建20个线程,但截至目前只发布只有一个(相同)的任务是于IOService的运行(只是为了让事情变得简单,并在这里得到根本原因)。 以下是当我在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]

我有两个问题:

  1. 为什么会这样,我的线程退出,甚至当我在一个while循环发布的任务?
  2. 为什么从JobClass输出即在变量a,b的值和c没有得到打印?

Answer 1:

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

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

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));
    }
}


Answer 2:

OK,我会是第一个承认我不知道提升,更特别是在地上挖个洞提高:: ASIO,但我知道一个海拉 - 很多关于线程池和工作人员。

一个假设的线程睡眠状态,直到收到新的工作,但如果他们不这样配置的话,他们很可能只是完成自己的线程proc和退出,A搬弄是非的标志,是这种情况是启动了一个游泳池,睡眠张贴任何工作之前的合理时间内,如果池中的线程都终止,他们没有正确地等待着。 提升文档的快速细读得到这个 ,它可能与你的问题。

关于这一点,是有可能,你的游泳池从main()入口点析构函数,其实,过早地杀死你的工作的船员? 我看到join_all,但停止()让我心惊肉跳。 如果它做什么,它的名字所暗示的,将解释很多。 据来自文档即停止()调用的说明:

为了实现关机,则应用程序将需要调用io_service对象的stop()成员函数。 这将导致io_service对象的run()调用尽快返回,放弃未完成的操作,并没有允许准备处理程序进行调度。

这立即关闭和被遗弃提及似乎可疑熟悉您目前的状况。

同样,我不知道提升:从亚当ASIO,但都被我这个我会检查启动配置为升压线程对象。 他们可能需要如何启动配置,如何等待,等有一定使用boost的众多样本:关于配置你所描述这里,即工作的船员模式非常的事情在网络上ASIO。 我看到的boost :: ASIO一吨左右,所以有可能许多相关或接近相关的问题为好。

请随时降级这一点,如果它是没有什么有用的,我道歉,如果是这样的话。



文章来源: ThreadPool using ASIO - Threads Exit, Task not performed