0

以前のアドバイス マルチスレッドアプリケーションに従って、私はそれを正しく行っていますか?

Boostを使用したスレッドセーフな数値ジェネレーターがあると思いますが、1000回の反復を入力するとプログラムがクラッシュします。グラフ化したときの出力.csvファイルは正しく見えますが、なぜクラッシュするのかわかりません。

それは_beginthreadを使用していて、誰もが私がよく知らないもっと(複雑な)_beingthreadexを使うべきだと言っています。誰かが例を推薦することができれば、私はそれを大いに感謝します。

また...誰かが、開始位置をカウントする配列の_beginthreadに2番目のパラメーターを適用する必要があると指摘しましたが、構造体を使用する以外に、複数のパラメーターを渡す方法がわかりません。構造体と_beginthreadはうまくいきません(ただし、ブーストスレッドを使用することもできます...)

#include <process.h>
#include <windows.h>
#include <iostream>
#include <fstream>
#include <time.h>
#include <random>
#include <boost/random.hpp>

//for srand48_r(time(NULL), &randBuffer); which doesn't work
#include <stdio.h>
#include <stdlib.h>

//#include <thread>

using namespace std;
using namespace boost;
using namespace boost::random;

void myThread0 (void *dummy );
void myThread1 (void *dummy );
void myThread2 (void *dummy );
void myThread3 (void *dummy );

//for random seeds
void initialize();

    //from https://stackoverflow.com/questions/7114043/random-number-generation-in-c11-how-to-generate-how-do-they-work
    uniform_int_distribution<> two(1,2);

    typedef std::mt19937 MyRNG;  // the Mersenne Twister with a popular choice of parameters

    uint32_t seed_val;           // populate somehow

    MyRNG rng1;                   // e.g. keep one global instance (per thread)
    MyRNG rng2;                   // e.g. keep one global instance (per thread)
    MyRNG rng3;                   // e.g. keep one global instance (per thread)
    MyRNG rng4;                   // e.g. keep one global instance (per thread)

//only needed for shared variables
//CRITICAL_SECTION cs1,cs2,cs3,cs4; // global

int main()
{

    ofstream myfile;
    myfile.open ("coinToss.csv");

    int rNum;

    long numRuns;
    long count = 0;
    int divisor = 1;
    float fHolder = 0;
    long counter = 0;
    float percent = 0.0;

    //?
    //unsigned threadID;

    //HANDLE hThread;

    initialize();

    HANDLE hThread[4];

    const int size = 100000;

    int array[size];

    printf ("Runs (uses multiple of 100,000) ");
    cin >> numRuns;

    for (int a = 0; a < numRuns; a++)
     {

            hThread[0] = (HANDLE)_beginthread( myThread0, 0, (void*)(array) );
            hThread[1] = (HANDLE)_beginthread( myThread1, 0, (void*)(array) );
            hThread[2] = (HANDLE)_beginthread( myThread2, 0, (void*)(array) );
            hThread[3] = (HANDLE)_beginthread( myThread3, 0, (void*)(array) );

            //waits for threads to finish before continuing
            WaitForMultipleObjects(4, hThread, TRUE, INFINITE);

            //closes handles I guess?
            CloseHandle( hThread[0] );
            CloseHandle( hThread[1] );
            CloseHandle( hThread[2] );
            CloseHandle( hThread[3] );

        //dump array into calculations
        //average array into fHolder

            //this could be split into threads as well
            for (int p = 0; p < size; p++)
             {
                counter += array[p] == 2 ? 1 : -1;
                //cout << array[p] << endl;
                //cout << counter << endl;
            }

            //this fHolder calculation didn't work
            //fHolder = counter / size;

            //so I had to use this
            cout << counter << endl;
            fHolder = counter;
            fHolder = fHolder / size;

            myfile << fHolder << endl;

    }
}

    void initialize()
    {

      //seed value needs to be supplied
      //rng1.seed(seed_val*1);

      rng1.seed((unsigned int)time(NULL));
      rng2.seed(((unsigned int)time(NULL))*2);
      rng3.seed(((unsigned int)time(NULL))*3);
      rng4.seed(((unsigned int)time(NULL))*4);
    };


void myThread0 (void *param)
{
    //EnterCriticalSection(&cs1); //aquire the critical section object

    int *i = (int *)param;

    for (int x = 0; x < 25000; x++)
    {
        //doesn't work, part of merssene twister
        //i[x] = next();
        i[x] = two(rng1);

        //original srand
        //i[x] = rand() % 2 + 1;

        //doesn't work for some reason.
        //uint_dist2(rng);

        //i[x] = qrand() % 2 + 1;
        //cout << i[x] << endl;
    }
    //LeaveCriticalSection(&cs1); // release the critical section object

}

void myThread1 (void *param)
{
    //EnterCriticalSection(&cs2); //aquire the critical section object

    int *i = (int *)param;

    for (int x = 25000; x < 50000; x++)
    {
        //param[x] = rand() % 2 + 1;
        i[x] = two(rng2);
        //i[x] = rand() % 2 + 1;
        //cout << i[x] << endl;
    }
    //LeaveCriticalSection(&cs2); // release the critical section object

}

void myThread2 (void *param)
{
    //EnterCriticalSection(&cs3); //aquire the critical section object

    int *i = (int *)param;

    for (int x = 50000; x < 75000; x++)
    {
        i[x] = two(rng3);
        //i[x] = rand() % 2 + 1;
        //cout << i[x] << endl;
    }
    //LeaveCriticalSection(&cs3); // release the critical section object

}

void myThread3 (void *param)
{
    //EnterCriticalSection(&cs4); //aquire the critical section object

    int *i = (int *)param;

    for (int x = 75000; x < 100000; x++)
    {
        i[x] = two(rng4);
        //i[x] = rand() % 2 + 1;
        //cout << i[x] << endl;
    }
    //LeaveCriticalSection(&cs4); // release the critical section object

}
4

1 に答える 1

0

これは実際には問題に対する正確な答えではありません (_beginThread がメモリ リークを起こしやすいことを読みました) が、ブースト スレッドのみを使用する v5 を作成しました (コメント行は削除されました)。ところで、どこでクラッシュしたのかわかりません

#include <process.h>
#include <windows.h>
#include <iostream>
#include <fstream>
#include <time.h>
#include <random>
#include <boost/thread.hpp>
#include <boost/random.hpp>

//for srand48_r(time(NULL), &randBuffer); which doesn't work
#include <stdio.h>
#include <stdlib.h>

//#include <thread>

using namespace std;
using namespace boost;
using namespace boost::random;

//for random seeds
void initialize();
void workerFunc1(void *dummy );
void workerFunc2(void *dummy );
void workerFunc3(void *dummy );
void workerFunc4(void *dummy );

    //from http://stackoverflow.com/questions/7114043/random-number-generation-in-c11-how-to-generate-how-do-they-work
    uniform_int_distribution<> two(1,2);

    typedef std::mt19937 MyRNG;  // the Mersenne Twister with a popular choice of parameters

    uint32_t seed_val;           // populate somehow

    MyRNG rng1;                   // e.g. keep one global instance (per thread)
    MyRNG rng2;                   // e.g. keep one global instance (per thread)
    MyRNG rng3;                   // e.g. keep one global instance (per thread)
    MyRNG rng4;                   // e.g. keep one global instance (per thread)

//only needed for shared variables
//CRITICAL_SECTION cs1,cs2,cs3,cs4; // global

int main()
{

    ofstream myfile;
    myfile.open ("coinToss.csv");

    int rNum;

    long numRuns;
    long count = 0;
    int divisor = 1;
    float fHolder = 0;
    long counter = 0;
    float percent = 0.0;

    //?
    //unsigned threadID;

    //HANDLE hThread;

    initialize();

    HANDLE hThread[4];

    const int size = 100000;

    int array[size];

    printf ("Runs (uses multiple of 100,000) ");
    cin >> numRuns;

    for (int a = 0; a < numRuns; a++)
     {

            thread workerThread1(workerFunc1, (void*)(array) );
            thread workerThread2(workerFunc2, (void*)(array) );
            thread workerThread3(workerFunc3, (void*)(array) );
            thread workerThread4(workerFunc4, (void*)(array) );


            //waits for threads to finish before continuing
            workerThread1.join();
            workerThread2.join();
            workerThread3.join();
            workerThread4.join();

            //dump array into calculations
            //average array into fHolder

            //this could be split into threads as well
            for (int p = 0; p < size; p++)
             {
                counter += array[p] == 2 ? 1 : -1;
                //cout << array[p] << endl;
                //cout << counter << endl;
            }

            //this fHolder calculation didn't work
            //fHolder = counter / size;

            //so I had to use this
            //cout << counter << endl;
            fHolder = counter;
            fHolder = fHolder / size;

            myfile << fHolder << endl;

    }
}

    void initialize()
    {

      //seed value needs to be supplied
      //rng1.seed(seed_val*1);

      rng1.seed((unsigned int)time(NULL));
      rng2.seed(((unsigned int)time(NULL))*2);
      rng3.seed(((unsigned int)time(NULL))*3);
      rng4.seed(((unsigned int)time(NULL))*4);
    };

//recieves array, and spot of array to work on,
void workerFunc1(void *param)
{

    int *i = (int *)param;

    for (int x = 0; x < 25000; x++)
    {
        //gets a random 1 or 2 value
        i[x] = two(rng1);
        //converts to -1 or +1, then adds it to sum (I would love to combine these two)
    }
    //return sum;
}

void workerFunc2(void *param)
{

    int *i = (int *)param;

    for (int x = 25000; x < 50000; x++)
    {
        //gets a random 1 or 2 value
        i[x] = two(rng2);
        //converts to -1 or +1, then adds it to sum (I would love to combine these two)
    }
    //return sum;
}

void workerFunc3(void *param)
{

    int *i = (int *)param;

    for (int x = 50000; x < 75000; x++)
    {
        //gets a random 1 or 2 value
        i[x] = two(rng3);
        //converts to -1 or +1, then adds it to sum (I would love to combine these two)
    }
    //return sum;
}

void workerFunc4(void *param)
{


    int *i = (int *)param;

    for (int x = 75000; x < 100000; x++)
    {
        //gets a random 1 or 2 value
        i[x] = two(rng4);
        //converts to -1 or +1, then adds it to sum (I would love to combine these two)
    }
    //return sum;
}
于 2012-10-14T04:37:52.680 に答える