判断sem信号量为零_操作系统——信号量

1,信号量的定义
	信号量是有一个整数值的对象
	调用sem_wait()(或P())和sem_post()(或V())函数来操作
	sem_wait()函数:先对信号量的值减1,然后判断如果其值小于0就会等待
	sem_post()函数:先对信号量的值加1,然后判断如果有等待的线程就将其唤醒
	当信号量的值为负数的时候,这个数的绝对值就是等待线程的个数
	sem_wait()和sem_post()在同一个线程中成对出现
2,信号量用作锁——二值信号量
	在用作锁中,信号量初始值设为1
	下面是一个例子

123a81fd1a23a35baaa6c0992bf61ab8.png
二值信号量

deb9af6ce6163c8b153e1f7be82e7385.png
追踪线程:两个线程使用一个信号量
	因为锁只有两种状态(持有和没有持有),所以这种用法也可称为二值信号量
3,信号量用作条件变量
	在用作条件变量中,信号量初始值设为0
	下面是一个例子

26797356f643987977a950df716eea48.png
父线程等待子线程

cb21bdc77bdb1448883187037a910041.png
情况一:父线程先于子线程运行

23109938511863ce60682677015022b7.png
情况二:子线程先于父线程运行
4,生产者/消费者问题(有界缓冲区问题)
	①尝试——解决互斥问题

552b1127df4d7f03d6e00b3728e793e8.png
	②最终可行的方案

51ca51771344d342f1f41ac841b3b009.png
           因为向缓冲区加入元素和从缓冲区获得元素是临界区,需要用锁保护起来。但是锁加的位置有讲究,
      如果锁加在信号量empty和full之间,即把这两个信号量包含起来,那么会导致死锁的情况,
      比如,如果消费者先运行,那么先获取锁,然后对full信号量执行sem_wait()函数,
      因为这时候full值为初始值0,因此会休眠等待被唤醒,但此时消费者仍然持有锁,
      然后生产者运行,首先要获取锁,但由于锁被消费者占用了,所以生产者会等待锁被释放,
     而消费者却在等信号量full,此时形成了一个循环等待,即为死锁情况。
5,读者——写者锁
	①读写公平

7d2a9605bcfc128e81088d3a1a063021.png
读写公平
	读者和写者在获取各自的锁之前要先抢一把总的锁——queue。分析如下:如果写者先运
行,先获得锁queue,然后获取自己的写者锁writelock,这时候发生中断,读者运行,也是先获取锁queue,
但由于锁queue被写者占用,读者就会等待,这时候再切回到写者,释放锁queue,唤醒了等待的读者,
然后读者获得锁,执行相应的操作。
        ②读者优先

314f1d1e59f096417441a27846be8e6e.png
读者优先
	分析:如果读者先运行,先获得锁lock,然后读者数量+1,进入判断,将写者锁writelock-1,这
时候发生中断,写者运行,发现锁writelock已经被占有,这时候就会等待读者释放writelock锁,
但如果此时有多个读者运行,那么这个时候写者就需要等所有的读者运行完才有可能得到运行,
这样就会导致读者饿死写者。
        ③写者优先

91b1440b5358d0c7a5c3a30d74886b93.png
写者优先
          分析:如果写者先运行,先获得读者的锁readlock,使readlock的值-1,写者的数量+1,进入判断,
获取总锁queue,如果这时候发生中断,切换到读者运行,先获取总锁queue,发现已经被写者占有,只能等切
回到写者,释放readlock锁,同时获取writelock锁,即使现在让读者运行也不能运行,因为总锁queue还没
有被写者释放,如果这时候再来应该写者,获取锁readlock,写者的数量+1,目前写者数量为2,
释放readlock锁,尝试获取writelock,由于被第一个写者占有,只能休眠,当第一个写者执行sem_post函数,
这时候会将第二个写者唤醒,第二个写者执行,只要还要有写者在运行,读者都没法获得锁,
这时候会出现写者饿死读者的情况。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值