我正在做一些有趣的事情,试图学习多线程 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;
}
}
有人可以解释为什么它不起作用吗?
答案 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;
}