2016-04-26 52 views
-1

作爲任務的一部分,我的一個教授給我的代碼看起來有點像這樣:這個thread_local RNG種子完成了什麼?

namespace 
{ 
    thread_local unsigned seed; // for use with rand_r 

    void run_custom_tests() { 
     // set this thread's seed 
     seed = 0; 

     // insert some random numbers into a map 
     std::map<int, int> m; 
     for (int i = 0; i < key_max; ++i) 
      m.insert(i, rand_r(&seed)); 

     auto random_operations = [&]() 
     { 
      // do more stuff with rand_r(&seed) 
     }; 

     std::thread t1(random_operations); 
     std::thread t2(random_operations); 
     t1.join(); 
     t2.join(); 
    } 

} // end anonymous namespace 

void test_driver() 
{ 
    run_custom_tests(); 
} 

我的問題是什麼是thread_local種子的目的是什麼?我知道你不能讓兩個線程訪問同一個全局變量。但爲什麼不把它變成本地的呢?由於seed僅用於填充該映射和lambda內部,並且每個線程都有自己的堆棧,所以本地變量不會實現相同的目標嗎?

我在作業上做得很好,因爲重點不在於瞭解thread_local的這種用法。但是我仍然對這個計劃的這個方面感到困惑。

+0

內'random_operations'聲明的局部變量,是的。如果它在外部作用域中聲明,這些線程將共享它,因爲lambda通過引用捕獲它。 – milleniumbug

+0

這個函數是唯一一個產生隨機數的函數,它在整個程序中只調用一次*(在運行程序期間的一次,而不是在代碼中的一個位置)?如果是的話,這沒有什麼區別。否則,以前的值會影響下一個值... – deviantfan

+0

@milleniumbug然後將lambda更改爲通過值捕獲'seed'解決該問題? – Max

回答

0

從Linux文件:

如RAND(),rand_r()返回在範圍[0,RAND_MAX]的僞隨機整數。 seedp參數是一個指向無符號int的指針,用於在調用之間存儲狀態。

前面的文檔中提到randrand_r不是線程安全的。

因此,必須將狀態按線程分開,否則必須使用互斥鎖保護呼叫。

裁判:http://linux.die.net/man/3/rand_r

+0

我知道。但是由於每個線程都有自己的堆棧,爲什麼種子不能成爲局部變量呢?這就是我在我的問題中提出的問題。 – Max

+0

@Max他可能已經將種子定位到lambda的本地,但是他必須使lambda可變,因爲它會修改它自己的狀態。也許他不想解釋那部分語言? –