linux 系统支持多进程与多处理器,这样对共享资源的访问会存在竞争状态,所以需要处理好对资源的互斥与同步。
共享资源访问出现竞争状态叫做并发,一般并发的来源有以下3种:
(1). 中断处理产生并发。
(2). 调度器可抢占导致进程间产生并发。
(3). 多处理器不同进程间的并发。
一般处理资源的互斥与同步有这几种方式: 自旋锁,信号量,互斥锁与原子变量。以下简单说明这几种方式的使用。
1. 自旋锁,自旋锁的使用会关中断,并且不能睡眠,所以自旋锁的使用不能时间太长。
(1). 包含头文件
#include <linux/spinlock.h>
(2). 定义自旋锁变量
spinlock_t my_spinlock;
(3). 初始化自旋锁变量
spin_lock_init(&my_spinlock);
(4). 锁定操作
spin_lock(&my_spinlock);
(5). 解锁操作
spin_unlock(&my_spinlock);
2. 信号量,信号量不会关中断,允许调用线程进入睡眠,会引起进程的切换。
(1). 包含头文件
#include <linux/semaphore.h>
(2). 定义信号量变量
struct semaphore my_sem;
(3). 初始化信号量变量
sema_init(&my_sem, 1);
(4). 信号量DOWN操作
down(&my_sem); 或 down_interruptible(&my_sem);
down函数表示进程不可打断,down_interruptible则可以打断。
(5). 信号量UP操作
up(&my_sem);
3. 互斥锁,互斥锁实际就是计数为1的信号量,是信号量的一种特例,并且对这种特例做了优化。
(1). 包含头文件
#include <linux/mutex.h>
(2). 定义互斥锁变量
struct mutex my_mutex;
(3). 初始化互斥锁变量
mutex_init(&my_mutex);
(4). 互斥锁加锁操作
mutex_lock(&my_mutex);
(5). 互斥锁解锁操作
mutex_unlock(&my_mutex);
4. 原子变量,它是共享资源中的简单整型变量,对它的操作可以保证原子性。这种操作速度快,不会浪费CPU等相关资源。
(1). 包含头文件
#include <asm/atomic.h>
(2). 定义原子变量
atomic_t my_atomicval;
(3). 原子变量的操作函数
atomic_inc(&my_atomicval);
atomic_dec(&my_atomicval);