无论在学习还是在生活中,做一件事情都有一个理由。
学习的时候要明白为什么要学这个
为什么 ,这个是为什么存在,存在的目的是什么?
怎么做, 这个怎么做可以达到要解决的问题。有哪些方法可以做
1 为什么要进行并发控制?
现代处理器有三大特性: 中断处理,多任务处理和多处理器--导致的多个进程,线程,CPU同时访问一个资源会发生错误,所以并发控制的目的是:对共用资源进行保护。
并发控制的方法
1 原子变量操作:不会在执行完毕前辈其他任务中断和打断.
其中API和原子类型定义在:include/asm/atomic.h;原子操作定义在内存中而不是寄存器中。
原子变量的操作方法:
i, 原子整形操作
存在目的:可能有时候共享的资源只是一个简单地整型数值。定义方法: atomic_t xxxx ;操作方法: atomic_t类型只能通过linux内核定义的专门的函数操作。1,定义宏变量 #define ATOMIC_INIT(i) { (i) } .2,设置atomic_t变量的值 atomic_set(v,i) ;3,读取atomic_t的值 atomic_read(v);4, 变量的加减法 atomic_add(int i,volatile atomic_t *v) / atomic_sub(int i,volatile atomic_t *v);5,变量自加自减 atomic_inc(volatile atomic *v) / atomic_dec(int i,volatile atomic_t *v) ;6,加减法测试 atomic_dec_and_test(volatile atomic_t *v) ;
ii, 原子位操作
存在的目的:根据bit位进行单独的操作一个数据操作方法 : 定义某个数据的指针
设置位:static inline void set_bit(int nr ,bolatile unsigned long *addr) ; //addr变量的第nr位置设置为1清除位:static inline void clear_bit(int nr ,bolatile unsigned long *addr) ;反转位:static inline void change_bit(int nr ,bolatile unsigned long *addr) ;设置并且返回之前的值: static inline int test_and_set_bit(int nr ,bolatile unsigned long *addr) ;static inline int tes t_and_clear _bit(int nr ,bolatile unsigned long *addr) ;static inline int test_and_change_bit(int nr ,bolatile unsigned long *addr) ;
非原子操作:在这个函数之前增加__表示非原子操作。
设置位:static inline void __set_bit(int nr ,bolatile unsigned long *addr) ; //addr变量的第nr位置设置为1清除位:static inline void __clear_bit(int nr ,bolatile unsigned long *addr) ;反转位:static inline void __change_bit(int nr ,bolatile unsigned long *addr) ;设置并且返回之前的值: static inline int __test_and_set_bit(int nr ,bolatile unsigned long *addr) ;static inline int __tes t_and_clear _bit(int nr ,bolatile unsigned long *addr) ;static inline int __test_and_change_bit(int nr ,bolatile unsigned long *addr) ;
2自旋锁
存在的目的:解决原子操作在多个函数来回运行不能处理的时候。
类型:struct spinlock_t xxx ;
使用方法:
定义和初始化自旋锁:struct spinlock_t lock =SPIN_LOCK_UNLOCKED ;
void spin_lock_init(&lock) ;
锁定自旋锁:#define spin_lock(&lock) ;
******需要保护的临界资源******
释放自旋锁: #define spin_unlock(&lock)
注意事项:自旋锁是一种忙等待
自旋锁不能被递归调用函数。
3信号量
存在的目的: 进程等待的时候会在等待列队中睡眠,唤醒后再从唤醒的地方开始执行
(只有能睡眠的进程才能使用信号量,而中断不能睡眠就不能使用信号量)
信号量操作:
类型: struct semaphore{
spinlock_t lock ;
unsigned int count ;
struct list_head wait_list ;
}
4完成量
struct completion {
unsigned int done ;
wait_queue_head_t wait ;
}