thistleknot
thistleknot

Reputation: 1158

c++ multithread array

i'm doing something for fun, trying to learn multithreading Problems passing array by reference to threads

but Arno pointed out that my threading via process.h wasn't going to be multi-threaded.

What I'm hoping to do is something where I have an array of 100 (or 10,000, doesn't really matter I don't think), and split up the assignment of values to each thread. Example, 4 threads = 250 values per thread to be assigned.

Then I can use this filled array for further calculations.

Here's some code I was working on (which doesn't work)

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

}

Can anyone explain why it isn't working?

Upvotes: 0

Views: 3554

Answers (2)

paddy
paddy

Reputation: 63451

You should be aware that rand is not thread-safe.

There's even a post about it on SO: Using stdlib's rand() from multiple threads

If you can find yourself a thread-safe random number generator, you would be far better off making a parallel loop using OpenMP, as it maintains a thread pool that is far more efficient than using the thread API.

Otherwise, it might pay to pass a struct into your thread function that gives you the array AND the length required:

struct ArraySlice
{
    ArraySlice( int *arr, size_t start, size_t end)
        : pBegin( arr + start )
        , pEnd( arr + end )
    {}

    int *pBegin, *pEnd;
};

Then to create your threads...

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

And in your thread function:

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

Upvotes: 0

WhozCraig
WhozCraig

Reputation: 66194

For starters, use _beginthreadex rather than _beginthread, which closes the thread handle on normal run-out. if the thread handle is closed before you begin that WFMO it will likely break immediately since one or more of the handles will be invalid.

Secondly whats with the i*2 on your handle list ? Sending a list of handle to WFMO with every other handle NULL is likely going to error immediately.

Third, WFMO has a maximum wait-list length of 64 threads, so your list of a thousand threads is going to guaranteedly puke as soon as you reach 65 or more.. You just might want to consider limiting that ceiling. The actual value is MAX_WAIT_OBJECTS (or close to that, i can't recall exactly).

And thats all before we even get to the protection of the array you're trying to share.

Upvotes: 1

Related Questions