I am new to multithreading in C and I had this question. I wrote the following code:
#include
#include
#include
You're passing the address of a variable the for
is changing (i
) so you're at the mercy of the scheduler. You should just pass a copy. As a cheap, not completely-kosher way:
pthread_create(&thread[i],&attr,test, (void*)i);
/* ... */
int i = (int)a;
Notice that you are passing in the address of i
as a parameter to your threads:
pthread_create(&thread[i],&attr,test,&i);
This means that all of your threads will be reading the same variable i
to determine which thread they are. That is, all five threads will look at the same variable to determine their thread number. Consequently, as the value of i
increments in your for
loop, all the threads will perceive their thread number changing to use the new value of i
. This is why you're sometimes seeing 5 come up as the thread number, and also explains the fact that you're often skipping numbers or seeing far too many duplicates.
To fix this, you will need to give each thread their own copy of i
. For example, you could do something like this:
int* myI = malloc(sizeof(int));
*myI = i;
pthread_create(&thread[i], &attr, test, myI);
And then have the threads free the pointer before terminating:
void* test(void *a)
{
int i=*((int *)a);
printf("The thread %d has started.\n",i);
pthread_mutex_lock(&m);
sleep(1);
printf("The thread %d has finished.\n",i);
pthread_mutex_unlock(&m);
pthread_exit(NULL);
free(a);
}
Alternatively, you could cast i
to a void*
and pass that in:
pthread_create(&thread[i],&attr,test, (void*)i);
If you do this, you would then have the threads cast their arguments directly back to int
, not to int*
:
void* test(void *a)
{
int i = (int)a;
printf("The thread %d has started.\n",i);
pthread_mutex_lock(&m);
sleep(1);
printf("The thread %d has finished.\n",i);
pthread_mutex_unlock(&m);
pthread_exit(NULL);
}
Hope this helps!