[英]Correct way to use rand_r for multithreaded programs in C/C++
所以,我需要一些C ++中多線程的幫助。 我想讓我的多個線程用800以下的隨機數調用函數usleep。但是,根據我的理解,rand_r必須在每個線程中以不同的整數播種。
我的困惑源於這樣一個事實,即如果我想為每個線程使用不同的整數rand_r,那么我該怎么做呢? 如果我不能創建隨機整數,我怎樣才能為每個線程使用不同的(即隨機)整數?
static unsigned int consumerseed = 1;
static unsigned int producerseed = 54321;
//producer thread:
void *producer(void *param) {
buffer_item rand;
while (1) {
//sleep for a random period of time:
int producersleeptime = rand_r(&producerseed)%500+100;
usleep(producersleeptime);
//produce an item:
//wait on both semaphores
//attempt to insert into buffer
//signal both semaphores
}
}
//consumer thread:
void *consumer(void *param) {
buffer_item rand;
while (1) {
//sleep for a random period of time:
int consumersleeptime = rand_r(&consumerseed)%600+200;
usleep(consumersleeptime);
//wait on both semaphores
//attempt to remove an item from buffer
//signal both semaphores
}
}
我將在程序頂部定義的靜態整數producerseed和consumerseed作為全局變量 。 我是這樣做的,因為我認為對rand_r的調用需要訪問一個靜態的,不變的內存位置。
這是正確的方法嗎? 或者我是否需要為每個線程使用不同的整數。 這會導致我的線程中出現任何競爭條件嗎? 生成的隨機數怎么樣 - 每次都會有所不同?
編輯1:好的,所以這個問題的答案基本上是不正確的 。 每個線程都需要一個唯一的種子整數。 這可以來自,例如,time()或p_thread_self()id。 我仍然對如何准確實現這一點感到困惑,但我將繼續努力並報告。 現在我決定使用p_thread_self作為每個線程的種子。
非常感謝您花時間尋找/回答。
在C ++ 11中,您可以使用std::random_device
在每個線程上創建另一個獨立種子。 這與您在單線程代碼中完全相同。 然后,您可以在std::this_thread
上調用thread::sleep()
。
#include <random>
#include <thread>
#include <chrono>
thread_local std::random_device rd; // used once only per thread to initialise RNG
thread_local std::mt19937 rng(rd()); // thread-specific RNG
std::uniform_int_distribution<int> uni(0,800); // guaranteed unbiased
// called possibly many times
std::this_thread::sleep_for(uni(rng)*std::chrono::microseconds);
特別地,不需要(ab)使用當前時間作為種子和/或其他相關種子。
time()
以獲取第一個種子。 然后,對於每個新線程,將一個添加到當前種子以獲取下一個種子。 例如,如果time()
返回100,那么你的種子將是100,101,102等。你的主線程需要將種子傳遞給每個線程作為線程參數的一部分。 編輯:
100
)並將其與線程ID(使用xor或add)混合。 這樣您就不必將種子傳遞給每個線程。 至於只使用線程id作為種子,那也可以。 但是,在新的運行中,您可能會獲得與先前運行相同的線程ID(取決於您的操作系統如何確定線程ID)。 因此,如果您不想依賴於操作系統如何生成線程ID,您仍應使用一些初始種子,例如時間。 我的困惑源於這樣一個事實,即如果我想為每個線程使用不同的整數rand_r,那么我該怎么做呢? 如果我不能創建隨機整數,我怎樣才能為每個線程使用不同的(即隨機)整數?
在這里,您需要使用特定於線程的變量。 所以你可以使用這些方法。
pthread_setspecific() & pthread_getspecific()
這用於創建全局變量,但仍然特定於每個線程(不共享):它們是特定於線程的全局變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.