Chinaunix首页 | 论坛 | 博客
  • 博客访问: 156336
  • 博文数量: 36
  • 博客积分: 802
  • 博客等级: 准尉
  • 技术积分: 717
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-02 22:47
文章分类
文章存档

2012年(36)

分类: LINUX

2012-08-04 19:30:24

二:读写锁
        互斥锁把试图进入我们称之为临界去的所有其他线程都阻塞住了,而读写锁则分两种情况
(1)只要没有线程只有某个给定的读写锁用于写,那么任意数目的线程可以持有该读写锁用于读。
(2)仅当没有线程持有某个给定的读写锁用于读或者写,才能分配该读写锁用于写。
       只要没有线程在修改某个给定的数据,那么任意数目的线程都是可以拥有读访问权限,仅当没有其他线程读或者修改某个给定的数据的时候,当钱线程才能修改他。
        这个对于某个给定资源的共享访问也称为共享-独占上锁,因为获取一个读写锁用于读称为共享锁,获取一个读写锁用于写称为独占锁。多读出者--单写入者
1:获取和释放读写锁

点击(此处)折叠或打开

  1. #include<pthread.h>
  2. int pthread_rwlock_rdlock(pthread_wrlock_t *rw)

  3. int pthread_rwlock_wrlock(pthread_rwlock_t *rw)

  4. int pthread_rwlock_unlock(pthread_rwlock_t *rw)

下面给出尝试获取一个读出或写入锁,但是如果不能马上获取,就返回一个EBUSY错误,而不是把调用线程投入睡眠

点击(此处)折叠或打开

  1. #include<pthread.h>

  2. int pthread_rwlock_tryrdlock(pthread_rwlock_t *rw);

  3. int pthread_rwlock_trywrlock(pthread_rwlock_t *rw);

2:读写锁的属性
静态初始化:PTHREAD——RWLOCK——INITIALIZER
动态初始化以及摧毁

点击(此处)折叠或打开

  1. #include<pthread.h>

  2. int pthread_rwlock_init(pthread_rwlock_t *rw);

  3. int pthread_rwlock_destory(pthread_rwlock_t *rw);

初始化某个读写锁时候,如果attr是个空指针,则使用默认属性,要赋予它非默认属性,则是永下面两个函数

点击(此处)折叠或打开

  1. #include<pthread.h>

  2. int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);

  3. int pthread_rwlockattr_destory(pthread_rwlockattr_t *attr);

当前定义的唯一属性是PTHREAD——PROCESS——SHARED,它制定相应的读写锁将在不同进程间共享,而不仅仅在一个进程的各个线程内进行共享。

以下函数获取和设置这个属性:

点击(此处)折叠或打开

  1. #include<pthread.h>

  2. int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr,int *valptr);

  3. int pthread_rwlockattr_setpshared(const pthread_rwlockattr_t *attr,int *value);

第一个函数在由valptr指向的证书中返回该属性的当前值,第二个函数把该属性的当前值设置为value,其值为PTHREAD_PROCESS_PRIVATE,或者PTHREAD_PROCESS_SHARED

这里有个结构体不得不说:

点击(此处)折叠或打开

  1. typedef struct
  2. {
  3. pthread_mutex_t rw_mutex;
  4. pthread_cond_t rw_condreaders;
  5. pthread_cond_t rw_condwriters;
  6. int rw_magic;
  7. int rw_nwaitreaders;
  8. int rw_nwaitwriters;
  9. int rw_refcount;
  10. }pthread_rwlock_t;
初始化成功后,标志成员rw_magic就被设置成RW_MAGIC,所有函数都测试该成员,以检测调用这是否向某个已经初始化的读写锁传递指针,读写锁被摧毁后,这个成员被置为0
rw_refcount=-1:这是一个写入锁
rw_refcount=0:这个锁可用
rw_refcount>0:当前容纳着多少个读出锁

3:线程取消
如果pthread_rwlock_rdlock的调用线程阻塞在其中的pthread_cond_wait调用上并随后被取消,它就在扔持有互斥锁的情况下种植。通过对方调用函数pthread_cancel()一个线程可以被同一个进程内的任何其他线程锁取消,唯一参数是线程ID

点击(此处)折叠或打开

  1. #include<pthread.h>

  2. int pthread_cancel(pthread_t tid);

  3. void pthread_cleanup_push(void(*function)(void *),void *arg);
  4. void pthread_cleanup_pop(int execute);
处理程序就是发生以下情况时候被调用的函数:
(1)调用线程被取消(pthread_cancel())
(2)调用线程自愿终止(pthread_exit())
pthread_cleanup_push的function参数是调用线程被取消时候锁调用的函数的地址,arg是它单个参数。pthread_cleanup_pop总是删除调用线程的取消清理栈中位于栈顶的函数,而且如果execute部位0,那就调用该函数。

点击(此处)折叠或打开

  1. #include<pthread.h>
  2. #include "pthread_rwlock.h"

  3. pthread_rwlock_t rwlock=PTHREAD_RWLOCK_INITIALIZER;
  4. pthread_t tid1,tid2;
  5. void *thread1(void *)
  6. {
  7. pthread_rwlock_rdlock(&rwlock);
  8. printf("thread1 got a read lock!\n");
  9. sleep(3);
  10. pthread_cancel(tid2);
  11. sleep(3);
  12. pthread_rwlock_unlock(&rwlock);
  13. return NULL;
  14. }
  15. void *thread2(void *arg)
  16. {
  17. printf("thread2 tries to obtains write lock!\n");
  18. pthread_rwlock_wrlock(&rwlock);
  19. printf("thread2 got a write lock");
  20. sleep(1);
  21. pthread_rwlock_unlock(&rwlock);
  22. return NULL;
  23. }
  24. int main(int argc,char *argv[])
  25. {
  26. void *status;
  27. pthread_setconcurrency(2); pthread_create(&tid1,NULL,thread1,NULL);
  28. sleep(1);
  29. pthread_create(&tid2,NULL,thread2,NULL);
  30. pthread_join(tid2,&status);
  31. if(status!=PTHREAD_CANCLED)
  32. printf("thread2 status=%p\n",status);
  33. pthread(tid1,&status);
  34. if(status!=NULL)
  35. printf("thread1 status=%p\n",status);

  36. printf("rw_refcount=%d,rw_nwaitreaders=%d,rw_nwaitwriters=%d\n",rwlock.rw_refcount,rwlock.rw_nwaitreaders,rwlock/rw_nwaitwriters);

  37. pthread_rwlock_destroy(&rwlock);
  38. exit(0);
  39. sleep(1);
  40. }
本程序第二个线程试图获取一个写入锁,可是这个不可能因为这个时候,第一个线程已经获取一个读出锁了,则底下部分都不被执行。
阅读(2423) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~