2012-10-10 49 views
0

我做得好玩,想学多线程 Problems passing array by reference to threadsC++多线程阵列

但阿诺指出,通过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

你已经注释掉了''标题,为什么?为什么不使用C++中的标准线程工具? –

回答

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; 
} 
+0

g:\ dev \ threaded.cpp ||在函数'int main()'中: g:\ dev \ threaded.cpp | 57 |错误:从'long unsigned int'无效转换为'void *'| || ===构建完成:1个错误,0个警告=== | – thistleknot

+1

这似乎是一条错误消息。这种形式对我来说没什么用处,但它对你应该是有用的。 – paddy

+0

这就是这行“hThread [i] = _beginthread(myThread,0,(void *)slice);” – thistleknot

1

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

其次你的手柄列表上的i * 2是什么?使用其他句柄NULL发送WFMO句柄列表可能会立即出错。第三,WFMO的最大等待列表长度为64个线程,因此,一旦达到65个或更多,您的千线程列表就会保证呕吐。您可能需要考虑限制该上限。实际值是MAX_WAIT_OBJECTS(或者接近于此值,我无法完全记得)。

这就是我们甚至在保护你试图分享的数组之前的一切。

+0

我只是在复制一个前面的例子,我不知道我* 2是什么。关于如何实现这一点,我有一个完全不同的想法,它不是每个元素的线程。我想有4个线程处理多达100个元素,然后将这100个元素数组翻转为主处理 – thistleknot

+0

副本来自[this](http://stackoverflow.com/a/12802981/1504523 )回答。 i * 2最初是** i * 2 + 1 **,当上面的行没有被注释掉时是有意义的。 – Arno

+0

对于MAX_WAIT_OBJECTS和_beginthreadex +1 – Arno