I am trying to implement a queue based worker using pthread. But I have some confusions about pthread_cond_wait()
.
class Worker
class Worker {
private:
pthread_t thread;
vector<int> queue;
bool stop;
pthread_mutex_t mutex;
pthread_cond_t cond;
public:
Worker() {
stop = false;
if (pthread_mutex_init(&mutex, NULL) != 0)
{
printf("\n mutex init failed\n");
}
if(pthread_cond_init(&cond,NULL) != 0){
printf("\n cond init failed\n");
}
}
~Worker() {
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
}
void interrupt(){
printf("Going to inturrupt\n");
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond); //broadcast also doesn't work
pthread_mutex_unlock(&mutex);
printf("inturrupted \n");
}
void condition_lock(){
pthread_mutex_lock(&mutex);
while(queue.size() == 0){
printf("Entering conditional lock\n");
pthread_cond_wait(&cond,&mutex);
}
pthread_mutex_unlock(&mutex);
}
void *run(){
printf("run\n");
while(!stop){
printf("Going for condition lock");
printf("size: %d\n",queue.size());
condition_lock();
printf("Exit from condition lock");
while(queue.size() > 0){
printf("item: %d\n",queue[0]);
queue.pop_back();
}
}
pthread_exit(NULL);
}
void push(int value){
pthread_mutex_lock(&mutex);
queue.push_back(value);
pthread_mutex_unlock(&mutex);
}
void join(){
void *status;
pthread_join(thread,&status);
}
static void *run_helper(void* context){
return ((Worker *)context)->run();
}
void stop_thread(){
stop = true;
interrupt();
}
void start_thread(Worker worker){
stop = false;
int status = pthread_create(&thread,NULL,run_helper,&worker);
}
};
Main
int main(){
Worker worker;
worker.start_thread(worker);
usleep(500000);
for(int i=0;i<5;i++){
worker.push(i);
worker.interrupt();
usleep(500000);
}
worker.stop_thread();
worker.join();
printf("Thread exit\n");
return 0;
}
output
run
Going for condition locksize: 0
Entering conditional lock
Going to inturrupt
inturrupted
Going to inturrupt
inturrupted
Going to inturrupt
inturrupted
Going to inturrupt
inturrupted
Going to inturrupt
inturrupted
Going to inturrupt
inturrupted
It's never return from pthread_cond_wait()
. I also don't understand how pthread_mutex_lock()
is working in void interrupt()
method because it should be already locked by void condition_lock()
.
edit
I have changed two changes in code as suggested.
1. use queue.size() == 0 instead of conditional variable.
2. Use mutex lock/unlock during queue.push_back()