首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Linux内核学习笔记七——内核同步机制和实现方式

Linux内核学习笔记七——内核同步机制和实现方式

一 原子操作
       指令以原子的方式执行——执行过程不被打断。
1 原子整数操作
       原子操作函数接收的操作数类型——atomic_t


//定义atomic_t v;
//初始化atomic_t u
= ATOMIC_INIT(0);//操作atomic_set(&v,4);      // v = 4atomic_add(2,&v);     // v = v + 2 = 6atomic_inc(&v);         // v = v + 1 = 7
//实现原子操作函数实现static inline void atomic_add(int i, atomic_t *
v){    unsigned long tmp;    int result;    __asm__ __volatile__("@ atomic_add\n"    "1:      ldrex      %0, [%3]\n"    "  add %0, %0, %4\n"    "  strex      %1, %0, [%3]\n"    "  teq  %1, #0\n"    "  bne 1b"      : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)      : "r" (&v->counter), "Ir" (i)      : "cc");}





2 原子位操作
[url=][/url]
//定义unsigned long word = 0;//操作set_bit(0,&word);       //第0位被设置1set_bit(0,&word);       //第1位被设置1clear_bit(1,&word);   //第1位被清空0//原子位操作函数实现static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p){       unsigned long flags;       unsigned long mask = 1UL << (bit & 31);       p += bit >> 5;       raw_local_irq_save(flags);       *p |= mask;       raw_local_irq_restore(flags);}



二 自旋锁
  原子位和原子整数仅能对简单的整形变量进行原子操作,对于复杂的数据复杂的操作并不适用。
需要更复杂的同步方法实现保护机制——锁。
  自旋锁:同一时刻只能被一个可执行线程持有,获得自旋锁时,如果已被别的线程持有则该线程进行循环等待锁重新可用,
然后继续向下执行。
过程如下:


    



使用锁得基本形式如下:
spinlock_t lock;//获取锁spin_lock(&lock);//临界区…… //释放锁spin_unlock(&lock);



使用自旋锁防止死锁:
       自旋锁不可递归,自旋处于等待中造成死锁;
       中断处理程序中,获取自旋锁前要先禁止本地中断,中断会打断正持有自旋锁的任务,中断处理程序有可能争用已经被持有的自旋锁,造成死锁。
       读写自旋锁:将锁的用途直接分为读取和写入。
三 信号量
  信号量:睡眠锁。如果有一个任务试图获取信号量时,
              信号量未被占用:该任务获得成功信号量;
              信号量已被占用:信号量将任任务推进等待队列,让其睡眠,处理器继续工作;当信号量被释放后,
        唤醒信号量队列中的任务,并获取该信号量。
              可有读写信号量。


      






继承事业,薪火相传
返回列表