Linux内核学习笔记七——内核同步机制和实现方式
- UID
- 1029342
- 性别
- 男
|
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);
使用自旋锁防止死锁:
自旋锁不可递归,自旋处于等待中造成死锁;
中断处理程序中,获取自旋锁前要先禁止本地中断,中断会打断正持有自旋锁的任务,中断处理程序有可能争用已经被持有的自旋锁,造成死锁。
读写自旋锁:将锁的用途直接分为读取和写入。
三 信号量
信号量:睡眠锁。如果有一个任务试图获取信号量时,
信号量未被占用:该任务获得成功信号量;
信号量已被占用:信号量将任任务推进等待队列,让其睡眠,处理器继续工作;当信号量被释放后,
唤醒信号量队列中的任务,并获取该信号量。
可有读写信号量。
|
|
|
|
|
|