Linux内核(六)信号量

本文深入探讨信号量和互斥锁的概念及其在进程间通信中的应用。信号量作为计数器,通过原子操作wait()和signal()保护共享资源,确保同一时刻只有一个进程访问。互斥锁则在临界区已加锁时挂起请求加锁的线程。文章还对比了计数信号量与二进制信号量的区别,以及它们如何用于资源管理和并发控制。

信号量本质上是一个计数器,这里可能就要问了,为啥不设置一个全局变量做计数器呢?是因为进程间是相互独立的,而这不一定能看到,看到也不能保证++引用计数为原子操作,而信号量的PV操作是原子操作。它和管道有所不同,它不以传送数据为主要目的,它主要是用来保护共享资源(信号量也属于临界资源),使得资源在一个时刻只有一个进程独享。

一个信号量 S 是个整型变量,它除了初始化外只能通过两个标准原子操作:wait () 和 signal() 来访问:

  • 操作 wait() 最初称为 P(荷兰语proberen,测试);
  • 操作 signal() 最初称为 V(荷兰语verhogen,增加);

多个进程在操作信号量时,如果轮不到它,就会挂起。下面sv就是实际信号量。一开始是0,如果一个进程发现是0,就使用并加1,然后别的进程发现不是0,接着加1并等待,用完之后释放减1,

(1)P(sv):如果sv的值大于零,就给它减1;如果它的值为零(为0代表有别的进程使用它),就挂起该进程的执行

(2)V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运行,如果没有进程因等待sv而挂起,就给它加1.

互斥锁则是当某个线程试图给一个已经处在加锁状态的临界区再次加锁时,该线程就会被临时挂起,一直等到该临界区被解锁后,才会被唤醒并继续执行。如果同时有多个线程等待某个临界区解锁,那下次被唤醒的进程取决于内核的调度策略,并没有固定的顺序。

操作系统通常区分计数信号量与二进制信号量。计数信号量的值不受限制,而二进制信号量的值只能为 0 或 1。因此,二进制信号量类似于互斥锁。事实上,在没有提供互斥锁的系统上,可以使用二进制信号量来提供互斥。二元信号量(Binary Semaphore)是最简单的一种锁(互斥锁),它只用两种状态:占用与非占用。所以它的引用计数为1。而普通信号量的引用计数是自己可以定值的。

计数信号量可以用于控制访问具有多个实例的某种资源。就是一个资源实际上可以被有限个进程同时使用,信号量的初值为可用资源数量。当进程需要使用资源时,需要对该信号量执行 wait() 操作(减少信号量的计数)。当进程释放资源时,需要对该信号量执行 signal() 操作(增加信号量的计数)。当信号量的计数为 0 时,所有资源都在使用中。之后,需要使用资源的进程将会阻塞,直到计数大于 0。大于0后,让哪一个进程从阻塞中恢复是通过调度实现的。

那么关于这个信号量的话,如果使用的话,也不可能说服务器进程与普通进程之间仅有一部分可以通信,没必要的,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值