最近在写一个OJ后台程序,一个主线程隔500毫秒读取一次数据库把任务放入队列中,起了4个线程用于处理任务(主要是得到任务,然后去数据库里读提交上来的代码).
主线程
while(true){
pthrea_lock_mutex(&conn_mutex);//数据库连接的mutex
//..读数据库..把任务放入队列中..
usleep(500000);
pthread_unlock_mutex(&conn_mutex);
}
子线程
while(true){
//得到一个任务
//去数据库里读出提交的代码
pthread_mutex_lock(&conn_mutex);//阻塞在这里
//读代码
pthread_mutex_unlock(&conn_mutex);
}
发现如果把pthread_mutex_unlock放在usleep()函数后面的话,其他4个线程就一直阻塞在lock上.
查了下资料,原来当这个线程从usleep()醒来后,unlock掉mutex之后,线程调度程序并不会立即让其他线程去占有这个mutex,由于当前线程刚从还有剩余时间片,于是又得到了这个mutex,而其他的线程就没有机会得到这个mutex.
解决方法就是把usleep(500000)和pthread_unlock_mutex(&conn_mutex)换个位置
while(true){
pthrea_lock_mutex(&conn_mutex);//数据库连接的mutex
//..读数据库放入队列中..
pthread_unlock_mutex(&conn_mutex);
usleep(500000);
}
结论:不要持有一个mutex太久,特别是不能在sleep()的时候持有一个mutex