Problems passing an array on stream links

I study threads and I found some simple examples.

What I hope to do is create 5 threads, each of which assigns a random number to an array of 20 int. Then, finally, there are 5 more threads that restore this array to a larger size of 100.

Here is some previous code I tried. I was hoping I could pass the array by reference, with no luck.

Any ideas would be appreciated, please keep in mind I'm completely new to threads

#include <process.h> #include <windows.h> #include <iostream> #include <fstream> #include <time.h> //#include <thread> using namespace std; void myThread (void *dummy ); void myThread2 (void *dummy ); 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; int array1[1000000]; int array2[1000000]; srand ( time(NULL) ); printf ("Runs (use multiple of 10)? "); cin >> numRuns; for (int i = 0; i < numRuns; i++) { _beginthread( myThread, 0, (void *) (array1) ); _beginthread( myThread2, 0, (void *) (array2) ); } } void myThread (void *param ) { int i = *(int *)param; for (int x = 0; x < 1000000; x++) { //param[x] = rand() % 2 + 1; i[x] = rand() % 2 + 1; } } void myThread2 (void *param ) { int i[1000000] = *(int *)param; for (int = 0; x < 1000000; x++) { i[x] = rand() % 2 + 1; } } 
+4
source share
3 answers

The first thing you need to understand:

  for (int i = 0; i < numRuns; i++) { _beginthread( myThread, 0, (void *) (array1) ); _beginthread( myThread2, 0, (void *) (array2) ); } 

The _beginthread call _beginthread immediately. They do not wait for the completion of the threads or even the beginning. It just pauses the thread in the OS scheduler and returns.

However, the code above is the end of the main() function. I highly doubt that when you create a Release, your threads are even initialized before your entire program exits. You need to create a mechanism by which your main thread will wait until the worker threads finish their work before your program shuts down. Doing so is beyond the scope of the SO message, but see CreateEvent () and WaitForMultipleObjects () .

The next thing you need to understand is the semantics of life and property that you send into streams. You pass pointers to arrays that are automatic variables in main() :

  int array1[1000000]; int array2[1000000]; 

As soon as the area in which these arrays are declared (here, main() ), the variables cease to exist. It is rare, if ever, to correctly pass a pointer to a variable with a local area into the workflow - never correct if the local area exits before the stream ends.

Dynamically allocating these arrays and then transferring ownership of the workflows will fix this problem. In doing so, be careful when managing the semantics of ownership of these objects / arrays.

+5
source

1. Casting:

Pay attention to the casting!

 void myThread (void *param ) { int *i = (int *) param; for (int x = 0; x < 1000000; x++) { i[x] = rand() % 2 + 1; } } 

2. Scope:

Both threads are started numRuns times. Launching them will take some time. Doing them too. main should not end without threads. You must keep track of threads using WaitForMultipleObjects . _beginthread () returns a waitable handle .

Implementation:

 int main() { long numRuns; HANDLE hThread[MAX_WAIT_OBJECTS]; cin >> numRuns; // numRuns to be smaller than MAX_WAIT_OBJECTS/2!!!! for (int i = 0; i < numRuns; i++) { hThread[i * 2] = _beginthread( myThread, 0, (void *) (array1) ); hThread[i * 2 + 1] = _beginthread( myThread2, 0, (void *) (array2) ); // or better use _beginthreadex(...) } WaitForMultipleObjects(numRuns * 2, hThread, TRUE, INFINITE); // bWaitAll flag set TRUE causes this statement to wait until all threads have finished. // dwMilliseconds set to INFINITE will force the wait to not timeout. } 

Thus, main will end only when all threads have completed their work.

3. Access:

Both arrays are declared in the main section, so the threads divide them. To protect access, you must introduce some kind of exclusivity. The simplest is the Critical Partition Object . When all threads2 gain access only to array2, and all flows1 gain access only to array1, I would suggest using 2 objects of the critical section. A critical section can be accessed only one thread at a time.

Implementation:

 CRITICAL_SECTION cs1,cs2; // global int main() { long numRuns; HANDLE hThread[1000]; // critical section object need to be initialized before aquired InitializeCriticalSection(&cs1); InitializeCriticalSection(&cs2); cin >> numRuns; for (int i = 0; i < numRuns; i++) { hThread[i * 2] = _beginthread( myThread, 0, (void *) (array1) ); hThread[i * 2 + 1] = _beginthread( myThread2, 0, (void *) (array2) ); } WaitForMultipleObjects(numRuns * 2, hThread, TRUE, INFINITE); } 

And the threads (only one shown here):

 void myThread1 (void *param ) { EnterCriticalSection(&cs1); //aquire the critical section object int *i = (int *) param; for (int x = 0; x < 1000000; x++) { i[x] = rand() % 2 + 1; } LeaveCriticalSection(&cs1); // release the critical section object } 

However: The whole story is still a bit obscure. You want multiple threads to fill the same array from start to finish at the same time. It sounds strange. When using the critical section objects described here, the threads will execute one after the other anyway. What exactly are you aiming for?

+3
source

Other answers cover the main points: there is another problem that is often a problem (at least on LINUX: not sure about windows)

 int array1[1000000]; int array2[1000000]; 

Declaring very large arrays because local variables run the risk of stack space overflowing, causing your program to crash.

+1
source

Source: https://habr.com/ru/post/1438668/


All Articles