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

手始めに、_beginthread ではなく _beginthreadex を使用してください。これにより、通常のランアウトでスレッド ハンドルが閉じられます。その WFMO を開始する前にスレッド ハンドルを閉じると、1 つ以上のハンドルが無効になるため、すぐに壊れる可能性があります。

次に、ハンドル リストの i*2 とは何ですか? 1 つおきのハンドルが NULL のハンドルのリストを WFMO に送信すると、すぐにエラーが発生する可能性があります。

第 3 に、WFMO の待機リストの最大長は 64 スレッドであるため、65 以上に達するとすぐに 1000 のスレッドのリストが確実に吐き出されます。その上限を制限することを検討することをお勧めします。実際の値は MAX_WAIT_OBJECTS (またはそれに近い、正確に思い出すことはできません) です。

共有しようとしているアレイを保護する前に、これですべてです。

于 2012-10-10T01:23:53.553 に答える
0

randはスレッドセーフではないことに注意してください。

SO に関する投稿もあります: Using stdlib's rand() from multiple threads

スレッド セーフな乱数ジェネレーターを見つけた場合は、スレッド API を使用するよりもはるかに効率的なスレッド プールを維持するため、OpenMP を使用して並列ループを作成することをお勧めします。

それ以外の場合は、配列と必要な長さを与える構造体をスレッド関数に渡す必要があります。

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 に答える