spin_lock叫自旋锁.就是当试图请求一个已经被持有的自旋锁.这个任务就会一直进行 忙循环——旋转——等待,直到锁重新可用(它会一直这样,不释放CPU,它只能用在短时间加锁).它是为了防止多个CPU同时访问一个共享资源(临界区).它一般用在中断上下文中,因为中断上下文不能被中断,也不能被调度.
自旋锁对信号量
需求 建议的加锁方法
低开销加锁 优先使用自旋锁
短期锁定 优先使用自旋锁
长期加锁 优先使用信号量
中断上下文中加锁 使用自旋锁
持有锁是需要睡眠、调度 使用信号量
进程间的sem.线程间的sem与内核中的sem的功能就很类似.
进程间的sem,线程间的sem功能是一样的.只是线程的sem,它在同一个进程空间,他的初始化,使用更方便.
进程间的sem,就是进程间通信的一部分,使用semget,semop等系统调用来完成.
内核中的sem 被锁定,就等于被调用的进程占有了这个sem.其它进程就只能进行睡眠队列.这与进程间的sem基本一致.
区别 |
Spin_lock |
semaphore |
保护的对象 |
一段代码 |
一个设备(必要性不强), 一个变量, 一段代码 |
保护区可被抢占 |
不可以 |
可以。 |
可允许在保护对象(代码)中休眠 |
不可以 |
可以。但最好不这样。 |
保护区能否被中断打断 |
可以,这样容易引发死锁。 最好是关了中断再使用此锁。 因为有可能中断处理例程也需要得到同一个锁。 |
可以。 |
其它功能 |
可完成同步,有传达信息的能力。 |
|
试图占用锁不成功后,进程的表现 |
不放开CPU,自己自旋。 |
进入一个等待队列。 |
释放锁后,还有其它进程等待时,内核如何处理 |
哪个进程得到运行的权力,它就得到了锁。 |
从等待队列中选一个出来占用此sem. |
内核对使用者的要求 |
被保护的代码执行时间要短,是原子的, 不能主动的休眠。 不能调用有可以休眠的内核函数。 |
|
风险 |
发生死锁 |
|
不允许锁的持有者二次请求同一个锁。 |
不允许锁的持有者二次请求同一个锁。 |
信号量在生产者与消费者模式中可以进行同步。
当sem的down和UP分别出现在对立函数中(读,写函数),其实这就是在传达一种信息。表示当前是否有数据可读的信息。
read_somthing()
{
down(设备) 占用了此设备 此时没有其它人都使用此设备上的所有操作(函数)
if(有数据)
{
读完它。
()
}
else
{
up(设备)
down(有数据的sem)sem=1表示有数据,为0表示无数据。
}
}
write_somthing()
{
down(设备) 占用了此设备 此时没有其它人都使用此设备上的所有操作(函数)
if(有数据)
{
不写。
up(设备)
return
}
else
{
写入数据
up(有数据的sem)sem=1表示有数据,为0表示无数据。
up(设备)
return;
}
}