linux的内核同步

linux的内核同步,作用是为了临界区的保护.主要有下面5种方式:

1:原子操作.执行过程中不能被打断的操作.

2:自旋锁,应用于多处理器环境.当得不到锁的时候,CPU就会在一直在做轮询判断.也就是说如果一个进程取不到自旋锁.也会一直判断下去,不会主动去调度其它进程代替当前进程.但是这样锁机制的开销极少.可以快速的开锁和加锁.持有自旋锁的进程一般都会对临界区有快速的处理

另外,内核还规定持有自旋锁的进程不能被抢占,这样做主要是出于系统性能考虑.如果一个持自旋锁的进程被调度出CPU.那其它需要这些锁的进程被调度进来之后,也只做 “自旋”工作.
3:信号量,需要对临界区长时间操作的情况下不太合适.因此,需要一种等待获锁的机制.这就是信号量.信号量在请求锁的时候,如果不成功,便会将进程投入睡眠.因此要在允许睡眠的场合使用信号量.
4:完成变量.在内核中经常有这样的需要,在一个进程中要等待某个进程完成某个事情.内核为其提供了一个简单的接口,其实它只是一个简化版的信号量而已.在kernel很多情况可以遇到这种实现.
完全变量在代码中的结构如下:
struct completion {
     //等待标志
     unsigned int done;
     //等待队列
     wait_queue_head_t wait;
};
5:读写信号量
通常受保护的数据是允许多个进程去读的。只需要保护写操作就可以了。如果多个读者去排队等待其它读者的操作完成的话,显然是有失效率的。读写信号量就是为了解瘊这个问题而产生的。读写信号量的等待队列是一个严格的FIFO.有以下几个特点:
1):读者去获取信号量的时候:
     1:如果临界区是空的或者有其它读者在操作,以时如果没有写者在排队,就把读者放进去。如果有  写者在排队,就把读者加入到等待队列。
     2:如果临界区有写者在操作。就把这个读者加入等待队列。
2):写者去获取信号量的时候:
     1:如果临界区是空的且等待队列为空。放这个写者进去。如果等待队不为空,就将其加至等待队列
     2:如果临界区中有读者在操作,就将其加入到等待队列.
3):释放信号量的时候:
     1:如果这个进程是读者。检查是不是临界区内的最后一个读者。如果是最后一个读者,检查是否有写者在等待。如果有。将写者唤醒。如果没有,直接退出。
     2:如果释放信号量是一个写者,通常会唤醒等待队列中的第一个进程
     2.1:如果这个进程是读者。那它后面的所有读者也会被唤醒(不包含写者后面的)
     2.2:如果这个进程是写者。那么它后面的所有等待进程继续睡眠.
总之:在这里要注意对待读者与写者的区别。在临界区中可以允许有多个读者,但不允许有多个写者。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值