使用 std::thread 组合来自多个线程的数组

Combining arrays from multiple threads using std::thread

我正在用 C++ 编写 Monte Carlo 程序,并使用 std::thread 在线程之间划分要跟踪的历史记录数。然而,这是我第一次尝试多线程,我遇到了一个问题,希望这个简化的代码能让我演示一下,希望能得到本站读者的一些建议。在这个简化的问题中,我正在调用函数 Summation,它使用 2 个线程生成一个 1X5 维随机数数组。当线程 return 它们的值时(不是真正 returned 因为它是一个全局变量),主程序然后有两个五维数组,每个数组对应一个不同的线程。我想将两个数组组合成一个数组,最终数组中的元素对应于不同线程生成的两个数组中相同元素的总和。不幸的是,来自每个线程的数组具有相同的名称,所以我不能简单地将两个不同的数组相加。推荐使用什么方法将两个 1X5 维数组组合成一个求和数组,其元素对应于每个线程的相同元素的总和?

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <cassert>
#include "boost/multi_array.hpp"

std::vector<float> Array;
std::mutex Array_mutex;

void Summation(int sample_size)
{
    std::lock_guard<std::mutex> guard(Array_mutex);
    for(int i = 0; i < sample_size; i++)
    {
        Array.push_back(rand() % 10 + 1);
    }
    std::cout << "\n";
}

int main(int argc, const char * argv[]) {
    int sample_size = 10;
    int Num_Threads = 2;
    int number_count = sample_size/Num_Threads;
    srand(time(NULL));
    std::vector<std::thread> Threads;
    for(int i = 0; i < Num_Threads; i++)
    {
        Threads.push_back(std::thread(Summation,number_count));
    }

    for(int i = 0; i < Num_Threads; i++)
    {
        Threads[i].join();
    }

    // - I would like to combine the arrays produced from each thread into a
    //   single array, where each element in the final array is the sum of
    //   the identical element in the array from each thread

    // i.e. Element 1(final) = Element 1(thread 1) + Element 1(thread2)
    //      Element 2(final) = Element 2(thread 1) + Element 2(thread2)
    //      Element 3(final) = Element 3(thread 1) + Element 3(thread2)

    return 0;
}

如果你想要每个线程一个向量,你实际上需要每个线程一个向量。就像向量的向量。

对于简单而幼稚的解决方案,例如

#include <iostream>
#include <array>
#include <random>
#include <thread>

void generate(const size_t size, std::array<float>& values)
{
    // Pseudo-random number generation stuff
    std::random_device rd;
    std::default_random_engine e1(rd());
    std::uniform_int_distribution<float> uniform_dist(1, 10);

    // Generate some values and add the array
    for (size_t i = 0; i < size; ++i)
        values[i] = uniform_dist(el);
}

int main()
{
    constexpr size_t number_values  = 10;
    constexpr size_t number_threads = 2;

    // An array of arrays, one sub-array per thread
    std::array<std::array<float, number_values>, number_threads>
        values;

    // An array of threads
    std::array<std::thread, number_threads> threads;

    // Create threads
    for (size_t i = 0; i < number_threads; ++i)
        threads[i] = std::thread(generate, number_values, std::ref(values[i]));

    // Wait for threads to finish
    for (size_t i = 0; i < number_threads; ++i)
        threads[i].join();

    // Now "combine" the values into a single array
    std::array<float, number_values> totals;
    for (size_t i = 0; i < number_values; ++i)
    {
        for (size_t j = 0; j < number_threads; ++j)
            totals[i] += values[j][i];
    }

    // Print the values
    for (const size_t i; i < number_values; ++i)
        std::cout << "Value #" << (i + 1) << " = " << totals[i] << '\n';
}

请注意,代码未经测试,甚至未编译,但理论上应该可以工作。 :)