Strange behavior of this simple pthread code

If I compile and run the code below

1 #include <iostream> 2 #include <pthread.h> 3 #include <cstdio> 4 #include <cstdlib> 5 6 #define NTHREADS 4 7 #define N 100 8 #define MEGEXTRA 1000000 9 10 using namespace std; 11 12 pthread_attr_t attr; 13 14 void *doWork (void *threadid) { 15 double A[N][N]; 16 int tid = *(reinterpret_cast<int *>(threadid)); 17 size_t myStackSize; 18 pthread_attr_getstacksize (&attr, &myStackSize); 19 cout << "Thread " << tid << ": stack size = " << myStackSize << " bytes" << endl; 20 21 for (int i = 0; i < N; i++) { 22 for (int j = 0; j < N; j++) { 23 A[i][j] = ((i * j) / 3.452) + (N - 1); 24 } 25 } 26 27 pthread_exit (NULL); 28 } 29 30 int main () { 31 pthread_t threads[NTHREADS]; 32 size_t stackSize; 33 34 pthread_attr_init (&attr); 35 pthread_attr_getstacksize (&attr, &stackSize); 36 37 cout << "Default stack size = " << static_cast<long>(stackSize) << endl; 38 39 stackSize = sizeof(double) * N * N + MEGEXTRA; 40 cout << "Amount of stack needed per thread = " << static_cast<long>(stackSize) << endl; 41 42 pthread_attr_setstacksize (&attr, stackSize); 43 cout << "Creating threads with stack size = " << static_cast<long>(stackSize) << endl; 44 45 int i[NTHREADS]; 46 for (int j = 0; j < NTHREADS; j++) { 47 sleep(1); 48 i[j] = j; 49 50 int rc = pthread_create(&threads[j], &attr, doWork, reinterpret_cast<void *>(&i[j])); 51 if (rc) { 52 cout << "Error Code: " << rc << endl; 53 exit (-1); 54 } 55 } 56 57 cout << "Created " << NTHREADS << " threads" << endl; 58 pthread_exit(NULL); 59 } 

I get the following output:

 Default stack size = 8388608 Amount of stack needed per thread = 1080000 Creating threads with stack size = 1080000 Thread 0: stack size = 1080000 bytes Thread 1: stack size = 1080000 bytes Thread 2: stack size = 1080000 bytes Created 4 threads Thread 3: stack size = 1080000 bytes 

but if I comment on a dream (1); on line 47, I get the following output

 Default stack size = 8388608 Amount of stack needed per thread = 1080000 Creating threads with stack size = 1080000 Created 4 threads Thread 3: stack size = 1080000 bytes Thread 2: stack size = 1080000 bytes Thread 1: stack size = 1080000 bytes Thread 9251904: stack size = 1080000 bytes /** ERROR should be Thread 0: stack size = 1080000 /** 

Can anyone explain what is happening? Why am I getting the wrong sleep conclusion (1)?

this is what i use to compile code

 g++ -Wall -Wextra -O2 -ggdb -pthread 5.cpp -o 5 
+4
source share
3 answers

This is because the main thread that the others create exits (vertically pthread_exit - and you still get the end of main ), before all the created threads can start, Array i destroyed and contains garbage while it is being read by all threads.

You need to wait, i.e. pthread_join - for your child threads before main can exit.

sleep buys you some time to execute threads, but it still depends on the OS to decide who works when. It may happen that sleep(1) enough or not enough, or that no one works until the postman arrives and delivers.

Call pthread_join and you will be safe.

+5
source

You did not mention if this is one main machine that you use.

Why do you think this is a wrong conclusion?

The OS can process threads in any order. Sleep will give this thread and turn on another thread a bash in the CPU. This is why the code will produce the result as indicated.

+1
source

When you comment out sleep(1); , the main thread will create all threads in one go and, presumably, will be faster than the system that creates these threads. The streams themselves run in parallel, so their output can be in any arbitrary order. When you use sleep(1); , threads will be created, the main thread will wait for the second, while this created thread will be scheduled, start and exit much less than a second, and then the next thread will be created.

created 4 threads will be written as soon as the loop ends. Without sleep(1); this loop ends just before any of the generated threads can start, so it will be transmitted before the stream exits. In sleep mode, all threads except the last one pass by their exit when the loop remains such that created 4 threads appear before the last created thread that has not yet been scheduled.

0
source

All Articles