2017-01-23 25 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(); }); 
を行うループから抜け出すために必要がある場合例えばそのデストラクタで - あなただけ pool_t自体が、この方法でループを抜けることができるように quit_exceptionプライベートタイプにしたいことがあり、正確な使用状況に応じて、

関連する問題