c++ - C/C++多线程程序使用rand_r的正确方法

标签 c++ c multithreading random

所以,我需要一些有关 C++ 中多线程的帮助。我想让我的多个线程使用低于 800 的随机数调用函数 usleep。但是,根据我的理解,rand_r 必须在每个线程中使用不同的整数作为种子。

My confusion源于这样一个事实,如果我想为每个线程的 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);

特别是,无需(滥用)使用当前时间作为种子和/或其他相关种子。

关于c++ - C/C++多线程程序使用rand_r的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29465758/

相关文章:

c++ - 哪些稳定的 c++11 特性可以安全使用

c - 按字母顺序对链接列表进行排序

c - 使用 .init_array 部分的段错误

java - 使用多线程java服务器获取客户端ID

java - 初始化时死锁

c++ - `void func() throw(type)` 有什么意义?

c++ - 使用 std::regex_replace 从替换模式引用整个匹配

c++ - 将元素添加到 std::map 时遇到问题

c - 使用管道发送消息 - C

java - 在同一方法中同步多个 block