Chinaunix首页 | 论坛 | 博客
  • 博客访问: 536142
  • 博文数量: 103
  • 博客积分: 2024
  • 博客等级: 上尉
  • 技术积分: 1294
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-08 21:17
文章分类

全部博文(103)

文章存档

2012年(2)

2011年(21)

2010年(80)

分类: LINUX

2010-09-25 10:59:19

3同步和锁机制
并发的可能情形:
1,中断
2,软中断
3,内核抢占
4,对称多处理
5,睡眠
死锁的避免
1,顺序加锁
2,不要重复请求同一个锁
3,设计力求简单
自旋锁和信号量是内核中主要的同步机制,用于保证对临界区的唯一性排他访问。如果进程不能获得自旋锁,将自旋等待,而不能获得信号量则睡眠。其中在单处理器系统中,自旋锁只是禁止内核抢占。
自旋锁和信号量的不同:
1,自旋锁是轻量级锁,信号量适用于长时间等待,其维护等待队列,上下文切换开销比较大
2,自旋锁能用于中断上下文,信号量只能用于进程上下文
3,在持有自旋锁时不能睡眠,也就是占用信号量的同时不能拥有自旋锁
4,需要和用户空间的代码同步时,信号量是唯一的选择
自旋锁:
spin_lock_init()
spin_lock()
spin_lock_irq()
spin_lock_irqsave()
信号量:
 16 struct semaphore {
 17     spinlock_t      lock;   //这个lock用于保护struct semaphore
 18     unsigned int        count;
 19     struct list_head    wait_list;
 20 };
sema_init()
down()
 53 void down(struct semaphore *sem)
 54 {
 55     unsigned long flags;
 56
 57     spin_lock_irqsave(&sem->lock, flags);
 58     if (likely(sem->count > 0))
 59         sem->count--;
 60     else
 61         __down(sem);
 62     spin_unlock_irqrestore(&sem->lock, flags);
 63 }
如果count>0,则获得这个信号量,成功返回。如果《=0,则进入__down的处理
207     struct task_struct *task = current;
208     struct semaphore_waiter waiter;
209
210     list_add_tail(&waiter.list, &sem->wait_list);
211     waiter.task = task;
212     waiter.up = 0;
213
214     for (;;) {
215         if (signal_pending_state(state, task))
216             goto interrupted;
217         if (timeout <= 0)
218             goto timed_out;
219         __set_task_state(task, state);
220         spin_unlock_irq(&sem->lock);
221         timeout = schedule_timeout(timeout);
222         spin_lock_irq(&sem->lock);
223         if (waiter.up)
224             return 0;
225     }
将进程添加到sem的等待队列中,设置进程的状态为TASK_UNINTERRUPTABLE或TASK_INTERRUPTABLE,调用schedule()进行进程的切换。

而up()则把第一个进程从等待队列中删除,并wake up()
up()
178 void up(struct semaphore *sem)
179 {
180     unsigned long flags;
181
182     spin_lock_irqsave(&sem->lock, flags);
183     if (likely(list_empty(&sem->wait_list)))
184         sem->count++;
185     else
186         __up(sem);
187     spin_unlock_irqrestore(&sem->lock, flags);
188 }

256 static noinline void __sched __up(struct semaphore *sem)
257 {
258     struct semaphore_waiter *waiter = list_first_entry(&sem->wait_list,
259                         struct semaphore_waiter, list);
260     list_del(&waiter->list);
261     waiter->up = 1;
262     wake_up_process(waiter->task);
263 }

阅读(2008) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-09-26 15:25:56

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com