为了避免多个进程对同一资源进行访问或多处理器并发产生竞争,内核采用锁机制来实现对共享数据的保护。首先简单分析一下操作系统之分类: |
一 操作系统分类 |
实时操作系统和分时操作系统。它们的共同特点是都是多任务的,但是主要区别在于应用场合,举个不恰当的例子实时操作系统应用于导弹发射、卫星发射等实时性要求较高的场合,而分时操作对实时性要求相对较低场合。 多任务操作系统分为两类:非抢占式多任务和抢占式多任务。 非抢占式多任务,就是每个进程不断的占用CPU,直到运行完毕或者是自己让出,别的进程才能使用CPU。 二 进程调度实际中我们发现进程可以分为两类: I/O消耗型:就是说进程频繁的和外界交互,比如要打开、浏览文件,要等待用户命令,要读取光盘上的数据。 处理器消耗型:就是说进程多数时间总是不断的在CPU里面运行,很少需要等待。所以我们应该区别对待这两种类型的进程。我们利用处理器遵循的原则是:吞吐量大和响应时间快。对于I/O消耗型,由于它需要频繁等待I/O,这样它需要较高的优先级来抢占当前运行进程,以确保当I/O条件满足后能马上得到CPU响应,并且它的时间片相对其它处理器消耗型进程来说更长。相反,处理器消耗型进程优先级相对就低了,并且其时间片没有必要太长。 三 自旋锁锁机制的原理是当进程进入CPU运行时,就会给它的代码上锁,以免别的CPU中的进程修改里面的代码。锁本身是一种互斥锁,即有“上锁”和“开锁”一说! 一个执行单元要想访问被自旋锁保护的共享资源,必须先得到锁,在访问完共享资源后,必须释放锁。如果在获取自旋锁时,没有任何执行单元保持该锁,那么将立即得到锁;如果在获取自旋锁时锁已经有保持者,那么获取锁操作将自旋在那里,直到该自旋锁的保持者释放了锁。 简单的说所谓自旋锁就是这样的一把锁:进程A进入CPU,锁上门运行,进程B来到CPU前,发现门被锁上了,于是等待进程A出来交出开锁钥匙。 缺点:一个被争用的自旋锁使得请求它的线程在等待锁重新可用时自旋(特别浪费处理器时间)。所以,自旋锁不应该被长时间持有。
Linux中的信号量是一种睡眠锁。如果有一个任务试图获得一个已被持有的信号量时,信号量会将其推入等待队列,然后让其睡眠。这时处理器获得自由去执行其它代码。当持有信号量的进程将信号量释放后,在等待队列中的一个任务将被唤醒,从而便可以获得这个信号量。
五 两者区别 虽然听起来两者之间的使用条件复杂,其实在实际使用中信号量和自旋锁并不易混淆。注意以下原则: 如果代码需要睡眠——这往往是发生在和用户空间同步时——使用信号量是唯一的选择。由于不受睡眠的限制,使用信号量通常来说更加简单一些。如果需要在自旋锁和信号量中作选择,应该取决于锁被持有的时间长短。理想情况是所有的锁都应该尽可能短的被持有,但是如果锁的持有时间较长的话,使用信号量是更好的选择。另外,信号量不同于自旋锁,它不会关闭内核抢占,所以持有信号量的代码可以被抢占。这意味者信号量不会对影响调度反应时间带来负面影响。 |
简单认识自旋锁和信号量
最新推荐文章于 2024-08-27 09:54:07 发布