2017-01-23 98 views
-1

下面是一些代码,显示了线程池的简单和短的实现。C++ 11带线程的线程池示例

该代码的灵感来源于this post

clang++ -std=c++11 threadpool.cpp -o threadpool -lpthread

编译执行时我得到了以下几点:

./threadpool 
terminate called without an active exception 

依我之见,问题是失控的功能pool_t::pop()及其无限循环。

我的问题是,如何优雅地退出循环?

被遗忘的代码 - 我的歉意 -

#include <vector> 
#include <queue> 
#include <thread> 
#include <mutex> 
#include <functional> 
#include <condition_variable> 

struct tasks_t 
{ 
    std::queue<std::function<void()>> queue; 

    std::mutex mutex; 
}; 

struct threads_t 
{ 
    std::vector<std::thread> vector; 

    std::condition_variable condition; 
}; 

struct pool_t 
{ 
    tasks_t tasks; 

    threads_t threads; 

    void pop() 
    { 
    while(true) 
    { 
     std::function<void()> task; 
     { 
     std::unique_lock<std::mutex> lock(tasks.mutex); 

     threads.condition.wait(lock,[this]{return !tasks.queue.empty();}); 

     task = tasks.queue.front(); 

     tasks.queue.pop(); 
     } 
     task(); 
    } 
    } 

    void push(std::function<void()> function) 
    { 
    { 
     std::unique_lock<std::mutex> lock(tasks.mutex); 

     tasks.queue.push(function); 
    } 
    threads.condition.notify_one(); 
    } 

    void start() 
    { 
    for (int i=0,j=std::thread::hardware_concurrency(); i!=j; ++i) 
    { 
     threads.vector.push_back(std::thread(&pool_t::pop,this)); 
    } 
    } 
}; 

#include <chrono> 
#include <iostream> 

std::function<void()> t0 = [] 
{ 
    std::cout << "t0" << std::endl; 
    std::this_thread::sleep_for(std::chrono::seconds(1)); 
    return; 
}; 

std::function<void()> t1 = [] 
{ 
    std::cout << "t1" << std::endl; 
    std::this_thread::sleep_for(std::chrono::seconds(2)); 
    return; 
}; 

int main() 
{ 
    pool_t pool; 

    pool.start(); 

    pool.push(t0); 

    pool.push(t1); 
} 
+6

看起来像忘了包含代码 – NathanOliver

回答

0

的情况下,例如最简单的办法往往是排队,简单地抛出一个特定类型的异常相比,可以捕获并采取行动任务...

struct pool_t { 
    class quit_exception {}; 
    tasks_t tasks; 
    threads_t threads; 

    void pop() 
    { 
    while (true) { 
     std::function<void()> task; 
     { 
     std::unique_lock<std::mutex> lock(tasks.mutex); 
     threads.condition.wait(lock, [this]{ return !tasks.queue.empty(); }); 
     task = tasks.queue.front(); 
     tasks.queue.pop(); 
     } 
     try { 
     task(); 
     } 
     catch (quit_exception &ex) { 
     return; 
     } 
    } 
    } 

当你需要跳出循环只是做的......

pool.push([](){ throw pool::quit_exception(); }); 

根据具体使用情况,您可能希望使quit_exception为私有类型,以便只有pool_t本身才能以此方式退出循环 - 例如在其析构函数中。