0

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

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

}

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

4

2 回答 2

1

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

其次,您的句柄列表中的 i*2 是什么?将句柄列表发送到 WFMO 并且每隔一个句柄 NULL 可能会立即出错。

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

在我们保护您尝试共享的阵列之前,这就是全部。

于 2012-10-10T01:23:53.553 回答
0

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

甚至在 SO 上有一篇关于它的帖子: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;
}
于 2012-10-10T01:06:31.407 回答