Tuấn Phạm Tuấn Phạm - 1 month ago 15
C Question

Incrementing variable's value with multithreading

I tried to write a Code with 2 threads, which should increment the 2 numbers x y to 100, everytime an increment happens, it should be printed out.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *inc_x(void *x_void_ptr){
int *x_ptr = (int *)x_void_ptr;
while (++(*x_ptr)<100) {
printf("x increment to %d \n",*x_ptr);
*x_ptr++;
}
return NULL;

}

void *inc_y(void *y_void_ptr){
int *y_ptr = (int *)y_void_ptr;
while (++(*y_ptr)<100) {
printf("y increment to %d \n",*y_ptr);
*y_ptr++;
}
return NULL;
}

int main()
{
int x = 0;
int y = 0;
printf("x: 0 , y : 0\n");
pthread_t inc_x_thread, inc_y_thread;
if (pthread_create(&inc_x_thread, NULL, inc_x, &x)) {
fprintf(stderr, "Error creating thread \n");
return 1;
}
if (pthread_create(&inc_y_thread, NULL, inc_y, &y)) {
fprintf(stderr, "Error creating thread \n");
return 2;
}
printf("%d , %d" , x,y);

return 0;
}


but my x,y values were not incremented. Can someone tell me why ? Thanks (I am new to C by the way).

Answer

There is no synchronization happening. In particular, you did not pthread_join() the threads.

What this means is that in all likelihood, the threads did not even run when you are trying to print out the results. They might have run, but you have no way of being sure.

Also, see comment by @mch above: You're indeed not incrementing the counter at all, to add to the previous. So even if the threads did run, the result wouldn't be what you want.

For correct operation, in general, you should either signal a condition variable (and wait on it on the consuming thread) to be sure a result is ready, or join threads prior to accessing the result. Signalling a condition variable is less heavyweight, so that's what you will want to do with repeated tasks rather than spawning/joining thousands of threads.

(In some cases, one can successfully share data between threads use atomic operations, but this is way too advanced for a beginner in threading. Too easy to make your life quite unhappy with that, stay with cond vars for now.)

You will normally also want to be sure that no "forgotten" threads are still running when the program exits, which is another good reason to call pthread_join even if you are not much interested in synchronization otherwise.

You may be inclined to think it doesn't matter much because the program exits anyway, and sometimes that's even true. But in general, this assumption is not valid. You may e.g. very well have garbage in files being written to, or half-written files, as threads are suddenly killed mid-operation.
Or you might have a worker thread segfault while the operating system suddenly pulls away the memory pages that it's still accessing from under its feet. Which "looks" perfectly normal, except when it doesn't.