2011-10-22 43 views
0

我運行以下示例從書c + +併發在行動,並傳遞函數a,b和c與它的提交,它打印彈出並確定返回true,但爲什麼不打印「啓動任務」 它似乎不運行任務)爲什麼不在彈出後運行任務並返回true?

#include <thread> 
#include <atomic> 
#include <vector> 
#include <queue> 

class join_threads 
{ 
    std::vector<std::thread>& threads; 
public: 
    explicit join_threads(std::vector<std::thread>& threads_):threads(threads_) 
    {} 
    ~join_threads() 
    { 
     for(unsigned long i=0;i<threads.size();++i) 
     { 
      if(threads[i].joinable()) 
       threads[i].join(); 
     } 
    } 
}; 

template<typename T> 
class thread_safe_queue 
{ 
private: 
    mutable std::mutex mut; 
    std::queue<T> data_queue; 
    std::condition_variable data_cond; 
public: 
    thread_safe_queue(){} 
    thread_safe_queue(thread_safe_queue const& other) 
    { 
     std::lock_guard<std::mutex> lk(other.mut); 
     data_queue=other.data_queue; 
    } 
    void push(T new_value) 
    { 
     std::lock_guard<std::mutex> lk(mut); 
     data_queue.push(new_value); 
     data_cond.notify_one(); 
    } 
    void wait_and_pop(T& value) 
    { 
     std::unique_lock<std::mutex> lk(mut); 
     //data_cond.wait(lk,[this]{return !data_queue.empty();}); 
     data_cond.wait(lk); 
     value=data_queue.front(); 
     data_queue.pop(); 
    } 
    std::shared_ptr<T> wait_and_pop() 
    { 
     std::unique_lock<std::mutex> lk(mut); 
     //data_cond.wait(lk,[this]{return !data_queue.empty();}); 
     data_cond.wait(lk); 
     std::shared_ptr<T> res(new T(data_queue.front())); 
     data_queue.pop(); 
     return res; 
    } 
    bool try_pop(T& value) 
    { 
     std::lock_guard<std::mutex> lk(mut); 
     if(data_queue.empty()) 
     return false; 
     value=data_queue.front(); 
     data_queue.pop(); 
     printf("pop"); 
     return true; 
    } 
    std::shared_ptr<T> try_pop() 
    { 
     std::lock_guard<std::mutex> lk(mut); 
     if(data_queue.empty()) 
     return std::shared_ptr<T>(); 
     std::shared_ptr<T> res(new T(data_queue.front())); 
     data_queue.pop(); 
     return res; 
    } 
    bool empty() const 
    { 
     std::lock_guard<std::mutex> lk(mut); 
     return data_queue.empty(); 
    } 
}; 

class thread_pool 
{ 
    std::atomic_bool done; 
    thread_safe_queue<std::function<void()> > work_queue; 
    std::vector<std::thread> threads; 
    join_threads joiner; 
    void worker_thread() 
    { 
     while(!done) 
     { 
      //printf("workerthread"); 
      std::function<void()> task; 
      if(work_queue.try_pop(task)) 
      { 
       printf("task start\n"); 
       task(); 
       printf("task end\n"); 
      } 
      else 
      { 
       std::this_thread::yield(); 
      } 
     } 
    } 
public: 
    thread_pool() : joiner(threads),done(false) 
    { 
     unsigned const thread_count=std::thread::hardware_concurrency(); 
     try 
     { 
      for(unsigned i=0;i<6;++i) 
      { 
       printf("push %d",i); 
       threads.push_back(std::thread(&thread_pool::worker_thread,this)); 
      } 
     } 
     catch(std::bad_alloc) 
     { 
      done=true; 
      throw; 
     } 
    } 
    ~thread_pool() 
    { 
     done=true; 
    } 
    template<typename FunctionType> 
    void submit(FunctionType f) 
    { 
     work_queue.push(std::function<void()>(f)); 
    } 
}; 
void a() 
{ 
    //while(true) 
    { 
     printf("a\n"); 
    } 
} 
void b() 
{ 
    //while(true) 
    { 
     printf("b\n"); 
    } 
} 
void c() 
{ 
    //while(true) 
    { 
     printf("c\n"); 
    } 
} 
int main() 
{ 
    printf("begin\n"); 
    thread_pool* pool = new thread_pool(); //start thread pool 
    printf("submit start\n"); 
    pool->submit((*a)); // pass function to queue 
    pool->submit((*b)); 
    pool->submit((*c)); 

    printf("submit finish\n"); 
    while(pool->done == false) 
     std::this_thread::sleep(std::milliseconds(1)); 
} 
+0

這是如何編譯的?除了丟失的包含,gcc告訴我'錯誤:'std :: atomic_bool thread_pool :: done'是private','error:'sleep'不是'std :: this_thread''的成員,而'error:'毫秒'不是'std''的成員(它是std :: chrono :: milliseconds) – Cubbi

回答

1

固定所有的編譯錯誤後,該編譯Linux上並運行GCC 4.6.1,產生以下的輸出:

begin 
push 0push 1push 2push 3push 4push 5submit start 
submit finish 
poptask start 
a 
task end 
poptask start 
b 
task end 
poptask start 
c 
task end 

在該點之後仍然在無休止的循環,因爲done永遠不會變成true

看來「任務啓動」實際上是打印的。

+0

非常感謝你,修正了所有警告之後,它可以運行,它似乎聲明優先級的木匠和完成問題 –

相關問題