Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2034899
  • 博文数量: 369
  • 博客积分: 10093
  • 博客等级: 上将
  • 技术积分: 4271
  • 用 户 组: 普通用户
  • 注册时间: 2005-03-21 00:59
文章分类

全部博文(369)

文章存档

2013年(1)

2011年(2)

2010年(10)

2009年(16)

2008年(33)

2007年(146)

2006年(160)

2005年(1)

分类:

2006-07-13 21:11:10

昨天同事的一个程序中需要用到读写锁,时值下班,也就没有多想。饭前简单的思虑了一下,想到了一种实现方式,回来后,就用pthread库实现了一个。编译的时候被告知和pthread库类型冲突,汗颜!难怪,我原以为pthread标准库没有提供rwlock,所以一切也就按照pthread自己的习惯(phtread_rwlock_xxx)进行了命名,不过一切还好,因为毕竟不用自己费劲了!;)
今天欣喜地告诉同事,结果他又告诉我,读者或者写者可能发生饿死!对他的测试程序进行详细分析后,得出结论:
pthread标准库没有任何问题,他对读写锁的使用有误,因为读写锁之间的区域也是属于临界区,如果读者两次进入临界区的时间间隔过短,且有多个读者相继进入临界区,那么写者将很有可能被饿死!同理,如果写者两次进入临界区的时间间隔也很短,那么读者也有可能挨饿!所以,无论写者和读者处于临界区的时间间隔都要尽量短,且在整个处理流程中,临界区所占有的比例也要足够小。
附上我写的rwlock实现,只是原理的实现,所有函数都没有检查返回值,所以,如果需要实际采用的话,可能需要略微处理一下。
鉴于程序简单,几近于原语描述,不做任何解释。
File:mthread_rwlock.h

#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_ */
File:mthread_rwlock.c

#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);
}

阅读(1649) | 评论(0) | 转发(0) |
0

上一篇:劫持系统库

下一篇:内核的执行体 -- 概观

给主人留下些什么吧!~~