读写锁及死锁

一、读写锁

有些公共数据修改的机会很少,但其读的机会很多。并且在读的过程中会伴随着查找,给这种代码加锁会降低我们的程序效率。读写锁可以解决这个问题。

读写锁本质上是一种自旋锁

读写锁及死锁_第1张图片

读者——写者:同步与互斥

写者——写者:互斥

读者——读者:共享、没关系

面试题:为什么消费者与消费者之间是互斥而读者与读者之间是没关系?

因为消费者会将数据拿走,而读者只访问不会将数据拿走

注意:写独占,读共享,写锁优先级高

        读写锁的策略:读者优先

                              写者优先

初始化


读写锁的属性一般设置为空

销毁


加锁和解锁

读写锁及死锁_第2张图片

  1 #include
  2 #include
  3 #include
  4 #include
  5 
  6 int counter;//计数器
  7 pthread_rwlock_t rwlock;//读写锁
  8 
  9 void* route_write(void *arg)
 10 {
 11     int no = (int)arg;
 12     while(1){
 13         int t = counter;
 14         pthread_rwlock_wrlock(&rwlock);//加写锁
 15         printf("write:thread(%d) id :%x inc %d to %d\n",no,pthread_self(),t,++counter);
 16         pthread_rwlock_unlock(&rwlock);//解锁
 17         sleep(2);
 18     }
 19 }
 20 
 21 void* route_read(void *arg)
 22 {
 23     int no = (int)arg;
 24     while(1){
 25         pthread_rwlock_rdlock(&rwlock);//加读锁
 26         printf("reader:thread(%d) id:%x data is : %d\n",no,pthread_self(),counter);
 27         pthread_rwlock_unlock(&rwlock);//解锁
 28         sleep(1);
 29     }
 30 }
 31 
 32 int main()
 33 {
 34     int i;
 35     pthread_t tid[8];
 36 
 37     pthread_rwlock_init(&rwlock,NULL);
 38 
 39     for(i = 0;i < 3;i++)//创建3个写者线程
 40     {
 41         int *p = (int*)malloc(sizeof(int));
 42         *p = i;
 43         pthread_create(tid+i,NULL,route_write,(void*)p);
 44     }
 45     for(i = 3;i < 8;i++)//创建5个读者线程
 46     {
 47         int *p = (int*)malloc(sizeof(int));
 48         *p = i;
 49         pthread_create(tid+i,NULL,route_read,(void*)p);
 50     }
 51     for(i = 0;i < 8;i++)
 52     {
 53         pthread_join(tid[i],NULL);
 54     }
 55     pthread_rwlock_destroy(&rwlock);
 56 }
        

读写锁及死锁_第3张图片

二、死锁

死锁是指多个线程因竞争资源而造成的僵局(互相等待)

1、产生死锁的4个条件:

a、互斥:某资源只能被一个进程使用,其他进程请求该资源时,只能等待,直到该资源被使用完毕

b、请求和保持条件:程序已经保持了至少一个资源,但是又提出了新要求,而这个资源被其他进程占用,自己占用的资源却保持不放

c、不可抢占条件:进程已获得的资源没有使用完,不能被抢占

d、循环等待条件:必然存在一个循环链

2、处理死锁的方法:

a、预防死锁:破坏死锁的四个必要条件中的任何一个或多个

b、避免死锁:和预防死锁的区别是,在资源动态分配过程中,用某种方式防止系统进入不安全的状态

c、检测死锁:运行时出现死锁,能及时发现死锁,把程序解脱

d、解除死锁:发生死锁后,解脱进程,通常撤销进程,回收资源,再分配给正处于阻塞状态的进程

3、预防死锁的方法:

a、破坏请求和保持条件

b、破坏不可抢占条件

c、破坏循环等待条件

4、避免死锁的方法:

a、加锁顺序

b、加锁时限

c、死锁检测


你可能感兴趣的:(linux环境)