繁体   English   中英

使用 C++ 中的线程生成和打印随机数

[英]Generating and printing random numbers using threads in C++

我目前正在做一个需要使用线程的项目。 然而,在处理这个项目之前,我想为自己创建一个简单的练习来测试我对线程的理解。

我拥有的是 2x 功能; 一个用于无限生成随机数,另一个用于打印此函数的输出。

这个随机数的值将通过指针不断更新。

据我了解,我需要一个互斥锁来防止在读取和写入此指针的值时出现未定义的行为。 我还需要从主函数中分离随机数生成器函数。

但是,我在尝试在 Visual Studio Code 中构建项目时遇到问题,我怀疑这是因为我的逻辑存在缺陷。

#include <bits/stdc++.h>
#include <iostream>
#include <thread>
#include <mutex>

std::mutex global_mu;

void generateRandomNum(int min, int max, int *number)
{
    while (true) {
    global_mu.lock();
    std::random_device rd;
    std::mt19937 rng(rd());
    std::uniform_int_distribution<int> uni(min, max);
    *number = uni(rng);
    global_mu.unlock();
    }
}

int main()
{
    int *int_pointer;
    int number = 0;
    int_pointer = &number;

    std::thread t1(generateRandomNum, 0, 3000, int_pointer);
    t1.detach();

    while(true) {
        global_mu.lock();
        std::cout << int_pointer << std::endl;
        global_mu.unlock();
    }
}

这看起来不对:

std::cout << int_pointer << std::endl;

您正在尝试打印指针的值,而不是打印它指向的int变量的值。 你要么应该这样做:

std::cout << *int_pointer << std::endl;

或这个:

std::cout << number << std::endl;

这看起来也可能不符合您的要求:

while (true) {
    ...
    std::random_device rd;
    std::mt19937 rng(rd());
    std::uniform_int_distribution<int> uni(min, max);
    *number = uni(rng);
    ...
}

您正在为循环的每次迭代构建和初始化一个新的随机数生成器。 您可能应该将 PRNG 移出循环:

std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> uni(min, max);
while (true) {
    ...
    *number = uni(rng);
    ...
}

最后,您可能永远不应该这样做:

while(true) {
    global_mu.lock();
    ...
    global_mu.unlock();
}

线程调用unlock()之后接下来要做的事情是什么? 接下来它会再次重新锁定同一个互斥锁。

我不想太技术化,但这种情况下的问题是最有可能获取互斥锁的线程将是刚刚释放它的线程,而不是等待很长时间的线程。 无论哪个线程首先进入互斥锁,都会使另一个线程饿死

解决饥饿问题的方法是仅将互斥锁锁定所需的最少时间。 例如,:

void generateRandomNum(int min, int max, int *number)
{
    std::random_device rd;
    std::mt19937 rng(rd());
    std::uniform_int_distribution<int> uni(min, max);
    while (true) {
        int temp = uni(rng);
    
        global_mu.lock();
        *number = temp;
        global_mu.unlock();
    }
}

int main()
{
    int *int_pointer;
    int number = 0;
    int_pointer = &number;

    std::thread t1(generateRandomNum, 0, 3000, int_pointer);
    t1.detach();

    while(true) {
        int temp;

        global_mu.lock();
        temp = number;
        global_mu.unlock();

        std::cout << temp << std::endl;
    }
}

如果这感觉就像你写了很多额外的行,你是对的。 多线程很难正确处理。 而且,为了从多线程程序中获得高性能,您将不得不编写额外的代码行,甚至可能使程序在每个 CPU 上比单线程程序做更多的工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM