I am trying to teach myself pthreads threading. I have the following source, which compiles and runs properly:
#include <stdio.h>
#include <pthread.h>
#define PTHREAD_COUNT 10
#define FREQ 5
void *thread_function(void *arg) {
int *incoming = (int *)arg;
int freqIdx;
for (freqIdx = 0; freqIdx < FREQ; freqIdx++)
fprintf(stdout, "Hello, world (thread %d)\n", *incoming);
return NULL;
}
int main(int argc, char **argv) {
pthread_t thread_IDs[PTHREAD_COUNT];
void *exit_status;
int threadIdx;
for (threadIdx = 0; threadIdx < PTHREAD_COUNT; threadIdx++) {
pthread_create(&thread_IDs[threadIdx], NULL, thread_function, &threadIdx);
pthread_join(thread_IDs[threadIdx], &exit_status);
}
return 0;
}
I get the following result:
Hello, world (thread 0)
Hello, world (thread 0)
Hello, world (thread 0)
Hello, world (thread 0)
Hello, world (thread 0)
Hello, world (thread 1)
...
Hello, world (thread 9)
If I pthread_create an array of pthread_t types over a loop, and then pthread_join in a separate loop, then things fail:
#include <stdio.h>
#include <pthread.h>
#define PTHREAD_COUNT 10
#define FREQ 5
void *thread_function(void *arg) {
int *incoming = (int *)arg;
int freqIdx;
for (freqIdx = 0; freqIdx < FREQ; freqIdx++)
fprintf(stdout, "Hello, world (thread %d)\n", *incoming);
return NULL;
}
int main(int argc, char **argv) {
pthread_t thread_IDs[PTHREAD_COUNT];
void *exit_status;
int threadIdx;
/* here I split the thread _create and _join steps into separate loops */
for (threadIdx = 0; threadIdx < PTHREAD_COUNT; threadIdx++)
pthread_create(&thread_IDs[threadIdx], NULL, thread_function, &threadIdx);
for (threadIdx = 0; threadIdx < PTHREAD_COUNT; threadIdx++)
pthread_join(thread_IDs[threadIdx], &exit_status);
return 0;
}
The output from this is quite wrong. Instead of getting five fprintf statements from each thread, I get one or two from, say, thread 2 and 3, and about 20 to 25 Hello, world statements from thread 0.
Why does this fail?
As others have stated, your problem is sharing the one
threadIdxvariable between all the threads. One way to fix this is to create one variable per thread: