C++ 多线程数组

c++ multithread array

本文关键字:数组 多线程 C++      更新时间:2023-10-16

>我正在做一些有趣的事情,试图学习多线程通过引用线程传递数组时出现问题

但 Arno 指出,我通过 process.h 的线程不会是多线程的。

我希望做的是我有一个 100 个数组(或 10,000 个,我认为并不重要),并将值的赋值拆分给每个线程。 例如,4 个线程 = 每个要分配的线程 250 个值。

然后我可以使用此填充数组进行进一步计算。

这是我正在处理的一些代码(不起作用)

#include <process.h>
#include <windows.h>
#include <iostream>
#include <fstream>
#include <time.h>
//#include <thread>
using namespace std;
void myThread (void *dummy );
CRITICAL_SECTION cs1,cs2; // global
int main()
{
    ofstream myfile;
    myfile.open ("coinToss.csv");
    int rNum;
    long numRuns;
    long count = 0;
    int divisor = 1;
    float holder = 0;
    int counter = 0;
    float percent = 0.0;
    HANDLE hThread[1000];

    int array[10000];
    srand ( time(NULL) );
    printf ("Runs (use multiple of 10)? ");
    cin >> numRuns;
    for (int i = 0; i < numRuns; i++)
    {
        //_beginthread( myThread, 0, (void *) (array1) );
        //???
        //hThread[i * 2] = _beginthread( myThread, 0, (void *) (array1) );
        hThread[i*2] = _beginthread( myThread, 0, (void *) (array) );
    }
     //WaitForMultipleObjects(numRuns * 2, hThread, TRUE, INFINITE);
     WaitForMultipleObjects(numRuns, hThread, TRUE, INFINITE);
}
void myThread (void *param )
{
    //thanks goes to stockoverflow
    //https://stackoverflow.com/questions/12801862/problems-passing-array-by-reference-to-threads
    int *i = (int *)param;
    for (int x = 0; x < 1000000; x++)
    {
        //param[x] = rand() % 2 + 1;
        i[x] = rand() % 2 + 1;
    }
}

谁能解释为什么它不起作用?

对于初学者,请使用 _beginthreadex 而不是 _beginthread,这会在正常跳动时关闭线程句柄。 如果在开始该 WFMO 之前关闭线程句柄,则它可能会立即中断,因为一个或多个句柄将无效。

其次,您的手柄列表中的 i*2 是怎么回事?将句柄列表与每隔一个句柄 NULL 一起发送到 WFMO 可能会立即出错。

第三,WFMO 的最大候补名单长度为 64 个线程,因此一旦您达到 65 个或更多,您的一千个线程列表肯定会呕吐。您可能只想考虑限制该上限。实际值是MAX_WAIT_OBJECTS(或接近该值,我记不清了)。

在我们开始保护您尝试共享的阵列之前,这些都已到来。

您应该知道rand不是线程安全的。

在SO上甚至有一篇关于它的帖子:从多个线程中使用stdlib的rand()

如果你能找到一个线程安全的随机数生成器,那么你最好使用 OpenMP 进行并行循环,因为它维护的线程池比使用线程 API 效率高得多。

否则,将一个结构传递到你的线程函数中,给你数组和所需的长度可能是值得的:

struct ArraySlice
{
    ArraySlice( int *arr, size_t start, size_t end)
        : pBegin( arr + start )
        , pEnd( arr + end )
    {}
    int *pBegin, *pEnd;
};

然后创建您的线程...

size_t arrayLength = 1000000;
size_t sliceLength = arrayLength / numRuns;
for (size_t i = 0; i < numRuns; i++)
{
    size_t start = i * sliceLength;
    size_t end = min( start + sliceLength, arrayLength );
    ArraySlice *slice = new ArraySlice(array, start, end);
    hThread[i] = (HANDLE)_beginthread( myThread, 0, (void*)slice );
}

在您的线程函数中:

void myThread (void *param )
{
    ArraySlice *slice = (ArraySlice*)param;
    if( !slice ) return;
    for( int *pos = slice->pBegin, *end = slice->pEnd; pos != end; pos++ )
    {
        *pos = rand();  // Except you need a thread-safe rand() function...
    }
    delete slice;
}