标题:
Linux内核学习笔记七——内核同步机制和实现方式
[打印本页]
作者:
yuyang911220
时间:
2017-5-15 11:22
标题:
Linux内核学习笔记七——内核同步机制和实现方式
一 原子操作
指令以原子的方式执行——执行过程不被打断。
1 原子整数操作
原子操作函数接收的操作数类型——atomic_t
//
定义
atomic_t v;
//初始化
atomic_t u
= ATOMIC_INIT(
0
);
//
操作
atomic_set(
&v,
4
);
//
v = 4
atomic_add(
2
,&v);
//
v = v + 2 = 6
atomic_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位被设置1
set_bit(
0
,&word);
//
第1位被设置1
clear_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
);
使用自旋锁防止死锁:
自旋锁不可递归,自旋处于等待中造成死锁;
中断处理程序中,获取自旋锁前要先禁止本地中断,中断会打断正持有自旋锁的任务,中断处理程序有可能争用已经被持有的自旋锁,造成死锁。
读写自旋锁:将锁的用途直接分为读取和写入。
三 信号量
信号量
:睡眠锁。如果有一个任务试图获取信号量时,
信号量未被占用:该任务获得成功信号量;
信号量已被占用:信号量将任任务推进等待队列,让其睡眠,处理器继续工作;当信号量被释放后,
唤醒信号量队列中的任务,并获取该信号量。
可有读写信号量。
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0