c ++多线程数组

时间:2012-10-10 00:52:11

标签: c++ arrays multithreading

我正在做一些有趣的事情,试图学习多线程 Problems passing array by reference to threads

但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;
    }

}

有人可以解释为什么它不起作用吗?

2 个答案:

答案 0 :(得分:1)

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

其次,你手柄清单上的i * 2是什么?将句柄列表发送到WFMO,每隔一个句柄NULL可能会立即出错。

第三,WFMO的最长等待列表长度为64个线程,所以一旦达到65个或更多,你的千条线程列表肯定会被呕吐。你可能只想考虑限制这个上限。实际值是MAX_WAIT_OBJECTS(或接近那个,我不记得确切)。

这就是我们甚至在你想要分享的阵列保护之前。

答案 1 :(得分:0)

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

甚至还有关于它的帖子:Using stdlib's rand() from multiple threads

如果您能找到一个线程安全的随机数生成器,那么使用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;
}