The last argument to pthread_create
is the issue. You pass a pointer to i
, but the value of i
changes as the main loop executes. There is no guarantee that i
is still 0
(or 1
or 2
or 3
) when your threads execute the print and you deference the pointer.
Try this simple change; it will give you the expected results:
int i;
int id[4] = { 1, 2, 3, 4 };
for (i = 0; i < NUM_COMSUMERS; i++) {
pthread_create(consumers+i, NULL, Consumer, id + i);
}
for (i = 0; i < NUM_PRODUCERS; i++) {
pthread_create(producers+i, NULL, Producer, id + i);
}
The above assumes NUM_CONSUMERS
and NUM_PRODUCERS
is 4, it will need reworked to make it more generic.
Alternatively, you don't necessary have to pass a pointer in, you could do the following:
for (i = 0; i < NUM_COMSUMERS; i++) {
pthread_create(consumers+i, NULL, Consumer, (void *)i);
}
for (i = 0; i < NUM_PRODUCERS; i++) {
pthread_create(producers+i, NULL, Producer, (void *)i);
}
And in your threads, don't dereference arg, just cast it to int
:
printf("producer thread: #%d in critical section\n", (int)arg);
and:
printf("consumer thread: #%d in critical section\n", (int)arg);
NOTE: You will get warnings casting between a pointer and an int on 64-bit systems.