Linux--POSIX信号量与读写锁

一:POSIX信号量:

1.基本概念

  • POSIX信号量和SystemV信号量作用相同,都是来实现同步或者互斥机制,本质也是计数器,通常用它来表示他所保护的临界资源的资源数目。

2.相关接口

初始化信号量:

  • int sem_init(sem_t *sem, int pshared, unsigned int value);//第二个参数0表示线程间共享,非零表示进程间共享。

等待信号集(相当于P操作)

  • int sem_wait(sem_t *sem);

发布信号(相当于V操作)

  • int sem_post(sem_t *sem);

销毁信号量

  • int sem_destroy(sem_t *sem);

3.小案例:

  • 上一节生产者–消费者的例子是基于链表的,这次基于环形队列,实现以下功能:如果队列为空那么保证生产者先运行;如果队列满了,保证消费者先运行。这次可以将队列的空间和队列的数据看作是两份不同的资源,而生产者只关心有没有”空间“资源,消费者只关心有没有”数据“资源,所以这里就需要有两个信号量来表示两份不同的资源,semBlank表示”空间“资源,初始值设为队列的总容量,semData表示”数据“资源,初始值设为0.
    这里写图片描述
    这里写图片描述
    注:这里不加锁的原因是因为,通过信号量已经保证了生产者与消费者在进行协调工作时不会访问同一个元素,从而在环形队列时生产和消费同时进行。

二:读写锁

1.读者写者模型:

写者模型与生产者消费者模型大致一样,也满足3,2,1规则

  • 3种关系:读者与读者(没有关系),写者与写者(竞争关系),读者与写着(互斥与同步关系)
  • 他们之间最大的区别是消费者会”取走”数据,而读者不会“取走‘数据。一般情况下,读者远远多于写者,所以,一般情况下,写者较读者优先权更高。

2.读写锁:

  • 有种情况是非常常见的,就是对于公共数据修改的机会比较少,相比较改写,他们读的机会反而更多。读写锁本质是一种自旋锁。(之前的互斥锁属于挂起等待锁)

自旋锁与挂起等待锁:

  • 它们都是是为实现保护共享资源而提出一种锁机制。其锁与挂起等待锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是挂起等待锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于挂起等待锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,”自旋”一词就是因此而得名。

3.相关接口:

初始化:

  • int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t*restrict attr);

读者写者锁:

  • int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
  • int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

解锁:

  • int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

销毁

  • int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

4.小案例

这里写图片描述
这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/virgofarm/article/details/80656280