Reputation: 173
I am currently learning operating systems and I am running the following code:
#include<iostream>
#include<pthread.h>
using namespace std;
#define Num_Threads 4
void *hello (void *arg){
int* p = (int *)arg;
cout << *p << endl;
return 0;
}
int main(){
int i = 0;
pthread_t tid[Num_Threads];
for (i = 0; i < Num_Threads; i++){
pthread_create(&tid[i], nullptr, hello, &i);
}
for (i = 0; i < Num_Threads; i++){
pthread_join(tid[i], nullptr);
}
return 0;
}
I use the following compiling commands in MaxOS:
g++ pThead.cpp -pthread -o test
./test
I am expecting this program to randomly output permutation of 0, 1, 2, 3 but it usually have some outputs like 3,0,0,0; 3,1,0,0 etc. I am a beginner to multithread so this question may look naive but I am grateful if someone can answer it.
Upvotes: 1
Views: 68
Reputation: 48615
Your threads are working on a pointer to i
and i
changes value while the threads are running.
So you also have a race condition where you are writing to and reading from the same variable i
from different threads simultaneously.
A possible solution is to create an array with an independent variable for each thread.
#include<iostream>
#include<pthread.h>
using namespace std;
#define Num_Threads 4
void *hello (void *arg){
int* p = (int *)arg;
cout << *p << endl;
return 0;
}
int main(){
pthread_t tid[Num_Threads];
int v[Num_Threads]; // a variable for each thread
for (int i = 0; i < Num_Threads; i++){
v[i] = i; // set a variable unique to each thread
pthread_create(&tid[i], nullptr, hello, &v[i]);
}
for (int i = 0; i < Num_Threads; i++){
pthread_join(tid[i], nullptr);
}
return 0;
}
Of course std::cout
is thread safe for individual calls but multiple calls can get interleaved when multiple threads are writing to it. So your std::endl
may not happen exactly between each output number (probably won't) and the numbers could occur in any order.
Upvotes: 4
Reputation: 5387
This is happening because you are printing value from the same address location and when the value will be read by the spawned thread is unpredictable. If the OS is starting threads too fast, you may see the values as 0, 1,2,3 but that will be unlikely.
Upvotes: 1
Reputation: 1
Your threads are running too quickly. Probably outputting a single number takes a few dozens of microseconds only, and your system don't schedule or run threads that fast.
Try to run some routine more complex than your hello
I am expecting this program to randomly output permutation of 0, 1, 2, 3
"randomly" is not the right word. You mean "unpredictably"
pthread_create(&tid[i], nullptr, hello, &i);
The &i
is wrong: all the threads get the same address.
Either allocate on heap:
int *p = malloc(sizeof(int));
if (!p) { perror("malloc"); exit(EXIT_FAILURE); };
*p = i;
pthread_create(&tid[i], nullptr, hello, p);
but then you have a memory leak (since you never free
)
or pass the integer directly (since int
fits in a word on most platforms)
pthread_create(&tid[i], nullptr, hellodirect, (void*)(intptr_t)i);
but then you need another function
void *hellodirect (void *arg){
int i = (int)(intptr_t)arg;
cout << i << endl;
return nullptr;
}
Upvotes: 0