2017-10-08 35 views
0

我需要運行一些線程數來處理對象數組。使用多線程處理對象數組 - 無效使用void表達式錯誤

因此,我已經寫這段代碼:

unsigned int object_counter = 0; 
while(object_counter != (obj_max - left)) 
{ 
    thread genThread[thread_num];//create thread objects 

    ///launch threads 
    int thread_index = 0; 
    for (; thread_index<thread_num; thread_index++) 
    { 
     genThread[thread_index] = thread(object[object_counter].gen_maps());//launch a thread 

     object_counter++; 
     if(object_counter == (obj_max - left) 
     { 
      break; 
     } 

    } 
    ///finish threads 
    for (; thread_index>0; thread_index--) 
    { 
     genThread[thread_index].join(); 

    } 
} 

基本上,有對象的數組(對象的數目= obj_max - left)。 每個對象都有一個稱爲gen_maps()的函數(void類型函數),用於生成地形。

我想要做的是使用多線程從所有對象運行所有gen_maps()函數。

最大線程數存儲在thread_num變量中。

但是,當我試圖編譯這段代碼我得到一個錯誤:

error: invalid use of void expression 
     genThread[thread_index] = thread(object[object_counter].gen_maps(), thread_index);//launch a thread 
                         ^

我怎樣才能解決這個問題?

回答

0

更可擴展的方式來管理任意大量的就業崗位具有較少數量的線程是使用線程池。

這是一個天真的實現(爲了更好的效率,會有2個條件變量來管理控制和狀態報告),它允許發起者添加任意數量的作業或線程並等待所有作業完成。

#include <thread> 
#include <condition_variable> 
#include <mutex> 
#include <vector> 
#include <functional> 
#include <deque> 
#include <cassert> 
#include <ciso646> 
#include <iostream> 

struct work_pool 
{ 
    std::mutex control_mutex; 
    std::condition_variable control_cv; 
    std::deque<std::function<void()>> jobs; 
    bool terminating = false; 
    std::size_t running = 0; 

    std::vector<std::thread> threads; 

    work_pool(std::size_t n = std::thread::hardware_concurrency()) 
    { 
     add_threads(n); 
    } 

    work_pool(const work_pool&) = delete; 
    work_pool& operator=(const work_pool&) = delete; 

    ~work_pool() 
    { 
     wait(); 
     shutdown(); 
    } 


    void add_threads(std::size_t n) 
    { 
     while (n--) 
     { 
      threads.emplace_back([this]{ 
       run_jobs(); 
      }); 
     } 
    } 

    void run_jobs() 
    { 
     while (1) 
     { 
      auto lock = std::unique_lock(control_mutex); 
      control_cv.wait(lock, [this] { 
       return terminating or not jobs.empty(); 
      }); 

      if (terminating) return; 

      ++running; 

      auto job = std::move(jobs.front()); 
      jobs.pop_front(); 

      lock.unlock(); 

      job(); 

      lock.lock(); 

      --running; 

      lock.unlock(); 

      control_cv.notify_one(); 
     } 
    } 

    void shutdown() 
    { 
     auto lock = std::unique_lock(control_mutex); 
     terminating = true; 
     lock.unlock(); 
     control_cv.notify_all(); 
     for (auto&& t : threads) { 
      if (t.joinable()) { 
       t.join(); 
      } 
     } 

     threads.clear(); 
    } 

    void wait() 
    { 
     auto lock = std::unique_lock(control_mutex); 
     control_cv.wait(lock, [this] { 
      return jobs.empty() and not running; 
     }); 
    } 

    template<class F> 
    void add_work(F&& f) 
    { 
     auto lock = std::unique_lock(control_mutex); 
     assert(not terminating); 
     jobs.emplace_back(std::forward<F>(f)); 
     lock.unlock(); 
     control_cv.notify_all(); 
    } 
}; 

// dummy function for exposition 
void generate_map() {} 

int main() 
{ 
    work_pool pool; 

    for(int i = 0 ; i < 100000 ; ++i) 
     pool.add_work(generate_map); 

    pool.wait(); 

    // maps are now all generated 

    std::cout << "done" << std::endl; 
} 
0

With object[object_counter].gen_maps() you call函數gen_maps並使用返回的值作爲線程函數。顯然gen_maps宣佈返回void這會導致您得到的錯誤。

你需要傳遞一個函數指針,然後通過它應該被稱爲作爲參數傳遞給線程對象:

thread(&SomeClass::gen_maps, object[object_counter])