分类:
2006-07-13 21:11:10
pthread标准库没有任何问题,他对读写锁的使用有误,因为读写锁之间的区域也是属于临界区,如果读者两次进入临界区的时间间隔过短,且有多个读者相继进入临界区,那么写者将很有可能被饿死!同理,如果写者两次进入临界区的时间间隔也很短,那么读者也有可能挨饿!所以,无论写者和读者处于临界区的时间间隔都要尽量短,且在整个处理流程中,临界区所占有的比例也要足够小。 |
#ifndef _MTHREAD_RWLOCK_H_ #define _MTHREAD_RWLOCK_H_ #include typedef struct _mthread_rwlock_t { pthread_mutex_t mutex; pthread_cond_t rdq, wrq; unsigned long nr_rd, nr_wr; unsigned long nr_rd_wtor, nr_wr_wtor; } mthread_rwlock_t; void mthread_rwlock_init(mthread_rwlock_t *lock); void mthread_rwlock_destroy(mthread_rwlock_t *lock); void mthread_rwlock_rdlock(mthread_rwlock_t *lock); void mthread_rwlock_rdunlock(mthread_rwlock_t *lock); void mthread_rwlock_wrlock(mthread_rwlock_t *lock); void mthread_rwlock_wrunlock(mthread_rwlock_t *lock); #endif /* _MTHREAD_RWLOCK_H_ */ |
#include #include "mthread_rwlock.h" void mthread_rwlock_init(mthread_rwlock_t *lock) { pthread_mutex_init(&lock->mutex, NULL); pthread_cond_init(&lock->rdq, NULL); pthread_cond_init(&lock->wrq, NULL); lock->nr_rd = 0; lock->nr_wr = 0; lock->nr_rd_wtor = 0; lock->nr_wr_wtor = 0; } void mthread_rwlock_destroy(mthread_rwlock_t *lock) { pthread_mutex_destroy(&lock->mutex); pthread_cond_destroy(&lock->rdq); pthread_cond_destroy(&lock->wrq); } void mthread_rwlock_rdlock(mthread_rwlock_t *lock) { pthread_mutex_lock(&lock->mutex); while(lock->nr_wr > 0){ lock->nr_rd_wtor ++; pthread_cond_wait(&lock->rdq, &lock->mutex); lock->nr_rd_wtor --; } lock->nr_rd ++; pthread_mutex_unlock(&lock->mutex); } void mthread_rwlock_rdunlock(mthread_rwlock_t *lock) { pthread_mutex_lock(&lock->mutex); lock->nr_rd --; if(lock->nr_rd == 0 && lock->nr_wr_wtor > 0) pthread_cond_broadcast(&lock->wrq); pthread_mutex_unlock(&lock->mutex); } void mthread_rwlock_wrlock(mthread_rwlock_t *lock) { pthread_mutex_lock(&lock->mutex); while(lock->nr_rd + lock->nr_wr > 0){ lock->nr_wr_wtor ++; pthread_cond_wait(&lock->wrq, &lock->mutex); lock->nr_wr_wtor --; } lock->nr_wr ++; pthread_mutex_unlock(&lock->mutex); } void mthread_rwlock_wrunlock(mthread_rwlock_t *lock) { pthread_mutex_lock(&lock->mutex); lock->nr_wr --; if(lock->nr_rd_wtor > 0) pthread_cond_broadcast(&lock->rdq); else if(lock->nr_wr_wtor > 0) pthread_cond_broadcast(&lock->wrq); pthread_mutex_unlock(&lock->mutex); } |