I am trying to learn multithreading in C . I am trying to pass elements of a vector as arguments to pthread_create. However, it is not working as expected.
#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <vector>
using namespace std;
void *count(void *arg)
{
int threadId = *((int *)arg);
cout << "Currently thread with id " << threadId << " is executing " << endl;
pthread_exit(NULL);
}
int main()
{
pthread_t thread1;
vector<int> threadId(2);
threadId[0] = 99;
threadId[1] = 100;
int retVal = pthread_create(&thread1, NULL, count, (void *)&threadId[0]);
if (retVal)
{
cout << "Error in creating thread with Id: " << threadId[0] << endl;
exit(-1);
}
pthread_t thread2;
retVal = pthread_create(&thread2, NULL, count, (void *)&threadId[1]);
if (retVal)
{
cout << "Error in creating thread with Id: " << threadId[1] << endl;
exit(-1);
}
pthread_exit(NULL);
}
The output which I get is:
Currently thread with id 99 is executing.
Currently thread with id 0 is executing
However, according to me, it should be:
Currently thread with id 99 is executing.
Currently thread with id 100 is executing.
What am I missing here ?
CodePudding user response:
int retVal = pthread_create(&thread1, NULL, count, (void *)&threadId[0]);
You have no guarantee, whatsoever, that the new execution thread is now running, right this very instant, without any delay.
All that pthread_create
guarantees you is that the thread function, thread1
, will begin executing at some point. It might be before pthread_create()
itself returns. Or it might be at some point after. It's really a big mystery when the new thread function will start executing, but you can take it to the bank that the new execution thread will begin. Eventually.
The same thing goes for your 2nd execution thread.
So, both execution thread could very well get in gear after your main()
returns, and after your vector gets destroyed. There's nothing in the shown code that guarantees that the execution threads will execute before the vector (whose contents get passed into them, in the manner shown) gets destroyed. And this leads to undefined behavior.
You will need to use other thread-related facilities that must be employed in order to synchronize multiple execution threads correctly. Additionally, you're using older POSIX threads. Modern C uses std::thread
s which offer many advantages over their predecessor, is completely type-safe (no ugly casts) and have numerous attributes that prevent common programming errors (however, in this instance std::thread
s also have no synchronization guarantee, this is usually the case with all typical execution thread implementations).