Reputation: 123
I am working on producer and consumer problems. I created one producer to put stuff into a bounded buffer and use multiple consumers to get data from the buffer. To check if every consumer is working I give each of them an ID and let them print it out.
Following are codes for creating multiple consumers.
#define CONSUMER_NUM 5;
pthread_t consumer[CONSUMER_NUM];
for(i=0;i<CONSUMER_NUM;i++){
int t = i;
pthread_create(&consumer[i],NULL,fun_consumer,(void*)&t);
} // pass i to the function fun_consumer to be an id of the thread
What I expected may look like:
Consumer 1
Consumer 2
Consumer 3
Consumer 4
Consumer 5
I understand that the output will usually not look like this due to the random execution of the threads. What I expected here is most the consumers will get into work. However, the truth is the program printed out like this:
Consumer 5
Consumer 5
Consumer 5
Consumer 5
Consumer 5
Only one consumer is used here. I tried "sleep", it can give me the output which I expected but caused slow execution. I am wondering if there is any better way to solve this problem?
Upvotes: 4
Views: 2543
Reputation: 62553
You are giving every thread a pointer to local variable i
. With each loop iteration i
is changing - and by the time the threads are actually launched and ready loop is done, and i
equals to 5 (last value).
However, this just one of the many potential outcomes. Your thread id could, indeed, read anything, as you have a classic data race in this code. You are accessing a variable from multiple threads, which is not protected in any way. Might even read 42, if luck has it this way.
Solution.
Either dynamically create a new variable for every thread and pass an address of this variable (you'd need to delete in the thread to prevent memory leak), or convert integer variable to pointer and provide this value to thread. To do this (somewhat) portably, your i
should actually be of a type uintptr_t
, rather than unsigned int
.
An example of how new variable can be created every time:
for (i=0 ; i<CONSUMER_NUM; ++i) {
int* id = malloc(sizeof(int));
*id = i;
pthread_create(&consumer[i],NULL,fun_consumer, id);
}
...
void* fun_consumer(void* arg) {
int id = *(int*)(arg);
free(arg)
// rest of code
Upvotes: 4
Reputation: 31143
You give them a reference to the variable i
, which changes in the loop. It executes so quickly that every thread sees it as 5.
You are still getting five threads, you are just sending the number incorrectly.
Upvotes: 1