2011-01-14 90 views
2

有一個線程(有無限循環中的一個函數的線程,當函數完成時生成數據)生成一些數據(例如隨機int)。 並且需要不時地獲取生成的數據的其他3個線程(無限循環中有一個函數的線程,功能啓動時需要數據)。所有這3個線程都希望在那個循環中修改那個int並返回一些不同的東西。由一個線程與其他線程數組共享數據

如何讓第一個線程生成的數據可以被其他線程訪問? (對不起 - 我是C++ nob,我可以使用boost庫,我請求你提供代碼和你的答案。)

+0

你想去哪裏把由消費者(3線)產生的數據?數據是否應該返回到被拍攝的地方? – AraK 2011-01-14 19:42:13

+0

@AraK:在完美世界將其返回到第一線(asincronosly),它從該數字隨機INT =) – Rella 2011-01-14 20:25:22

回答

3

這是一種原始的例子,演示如何創建可以生成隨機數,並把它們放在一個隊列,和三個消費者線程從隊列中取出的隨機數,並打印出來,如果隨機數僅是奇數線程。這個例子可以大大提高,許多最佳實踐不遵循解釋的基礎設施的緣故(thread_group,互斥和隨機數生成全部採用升壓):

#include <iostream> 
#include <queue> 
#include <boost/thread.hpp> 
#include <boost/thread/mutex.hpp> 
#include <boost/random.hpp> 
#include <boost/bind.hpp> 

std::queue<int> random_stream; 
boost::mutex random_stream_mutex, output_mutex; 
// create a random number generator similar to good ol' std::rand! 
boost::mt19937 rand_generator; 
boost::uniform_int<> distribution; 
auto random_producer = boost::bind(distribution, rand_generator); 

bool isodd(int number) 
{ return number % 2 == 1; } 

void random_generator() 
{ 
    for(;;) 
    { 
     // generate a random number, then lock the queue and push 
     // the number into it. 
     int random_number = random_producer(); 
     random_stream_mutex.lock(); 
     random_stream.push(random_number); 
     random_stream_mutex.unlock();  
    } 
} 

void output_odd_randoms() 
{ 
    for(;;) 
    { 
     // lock the queue then extract the number. 
     random_stream_mutex.lock(); 
     int random_number = random_stream.front(); 
     random_stream.pop(); 
     random_stream_mutex.unlock(); 
     // print the extracted number if it is odd! 
     if(isodd(random_number)) 
     { 
      output_mutex.lock(); 
      std::cout << boost::this_thread::get_id() << ": " 
       << random_number << std::endl; 
      output_mutex.unlock(); 
     } 
    } 
} 

int main() 
{ 
    // create the producer and the consumers! 
    boost::thread_group threads; 
    threads.create_thread(random_generator); 
    threads.create_thread(output_odd_randoms); 
    threads.create_thread(output_odd_randoms); 
    threads.create_thread(output_odd_randoms); 
    // wait for ever! :) 
    threads.join_all(); 
} 

正如你看到的,代碼使用全局變量但封裝數據是一個更好的主意。另外,使用RAII鎖定機制更加優雅,但修改代碼以添加它們是微不足道的。

希望幫助,

3

有很多方法可以做到這一點,具體取決於細節。既然你沒有提供很多細節,讓我們繼續簡單和防彈。

  • 創建一個類
  • 加入私有數據成員來存儲數據
  • 添加線程安全 get和put方法來讀取和寫入數據
  • 建設全局命名空間
  • 編寫您的線程以根據需要使用獲取和放置方法

您如何製作線程安全獲取和放置方法?

  • 爲您的班級添加一個私人互斥。
  • 鎖定進入get和put方法的互斥鎖
  • 從get和put方法退出時解鎖互斥鎖。

事情是這樣的:

class mySafeData 
{ 
public: 
    void Set(int i) 
    { 
     myMutex.lock(); 
     myData = i; 
     myMutex.unlock(); 
    } 
    void Get(int& i) 
    { 
     myMutex.lock(); 
     i = myData; 
     myMutex.unlock(); 
    } 
private: 
    int myData; 
    boost::mutex myMutex; 

}; 

這種方法效率不高。恕我直言,使用最簡單和最容易理解的技術來獲得代碼工作非常重要。一旦它正在工作,那麼,如果性能是一個問題,代碼可以被優化。