mardi 29 avril 2014

pthreads in c coming back with unexpected results


Vote count:

0




I'm using 2 unsynchronized threads to increment a global volatile int from 0 to 10000000. As expected, the int sometimes ends up at 10000001.


However, I'm also keeping count of how many times both threads execute their increment operations with a thread-specific local variable, and that one overshoots massively. Here's the code:



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

volatile int x = 0;


void* incThread(void* x) {
int* y;
y = malloc(sizeof(int));
*y = 0;

printf("tstart\n");

while(*((int*)x) < 10000000) {
*y = *y + 1;
*((int*)x) = *((int*)x) + 1;
if(*y % 1000000 == 0) {
printf(">thread at %i\n", *y));
}
}

printf("tend\n");

pthread_exit(y);
}



int main(int argc, char* argv[]) {

pthread_t thread1;
pthread_t thread2;

volatile int* xp;
xp = &x;

int* ret1;
int* ret2;


printf("\n\n\nTHREAD LAUNCH PROGRAM\n");
printf("-------------------------------------\n");
printf("I'll launch two threads.\n");
printf("Both will try incrementing the global value x to 10000000 before exiting.\n\n");


pthread_create(&thread1, NULL, incThread, (void*)xp);
pthread_create(&thread2, NULL, incThread, (void*)xp);
pthread_join(thread1, (void**) &ret1);
pthread_join(thread2, (void**) &ret2);


printf(" Thread01 exited after %i loops.\n", *ret1);
printf(" Thread02 exited after %i loops.\n", *ret2);
printf(" --------\n");
printf(" => %i total\n", ((*ret1)+(*ret2)));
printf("\n");
printf("x ended up at %i.\n", x);
printf("\n");

return 0;
}


So, running this results in it printing out zany results for the threads' iteration counters (int y in incThread()); for example, Thread01's y = 5801001 and Thread02's y = 5456675 for a total of more than 112% the expected value, 10000000. Meanwhile, x itself ends up at 10000000 or one higher, as expected.


What gives? How can the iteration counts end up this high?


OS Info and what I thought should be happening: The virtual debian 7.1 this whole thing is running on has its affinity set to one CPU core. I'd expect the virtual OS to open 3 threads in the program's process. Then, as it's iteratively switching from process to process as part of its regular execution cycle, it should also keep switching through every processes threads (main thread and custom threads 1&2 in this one's case) for as long as its focusing on that specific process.


So, there's a main thread launching t1 and t2, then waits for thread1 to finish, as soon as that's done it waits for thread2 to finish, then continues printing the results. But as far as I understand, none of this explains how y can deviate from x by this much.



asked 30 secs ago

Jake

61





Aucun commentaire:

Enregistrer un commentaire