在code review中,我会发现不少人喜欢在pthread_mutex_lock()和pthread_mutex_unlock(()之间调用 pthread_cond_signal或者pthread_cond_broadcast函数,从逻辑上来讲,这种使用方法是彻底正确的。可是在多线程环境中,这种使用方法多是低效的。posix1标准说,pthread_cond_signal与pthread_cond_broadcast无需考虑调用线程是不是mutex的拥有者,也就是说,能够在lock与unlock之外的区域调用。若是咱们对调用行为不关心,那么请在lock区域以外调用吧。这里举个例子:
咱们假设系统中有线程1和线程2,他们都想获取mutex后处理共享数据,再释放mutex。请看这种序列:
1)线程1获取mutex,在进行数据处理的时候,线程2也想获取mutex,可是此时被线程1所占用,线程2进入休眠,等待mutex被释放。
2)线程1作完数据处理后,调用pthread_cond_signal()唤醒等待队列中某个线程,在本例中也就是线程2。线程1在调用pthread_mutex_unlock()前,由于系统调度的缘由,线程2获取使用CPU的权利,那么它就想要开始处理数据,可是在开始处理以前,mutex必须被获取,很遗憾,线程1正在使用mutex,因此线程2被迫再次进入休眠。
3)而后就是线程1执行pthread_mutex_unlock()后,线程2方能被再次唤醒。
从这里看,使用的效率是比较低的,若是再多线程环境中,这种状况频繁发生的话,是一件比较痛苦的事情。因此以为,若是程序不关心线程可预知的调度行为,那么最好在锁定区域之外调用他们。 php
对于
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
,必定要在mutex的锁定区域内使用。
若是要正确的使用pthread_mutex_lock与pthread_mutex_unlock,请参考
pthread_cleanup_push 和pthread_cleanup_pop宏,它可以在线程被cancel的时候正确的释放mutex! html