当多个进程在同一时间段访问同一资源时,就容易引起相应错误。为了保护临界资源,Linux有如下三种机制:
1.原子操作
利用原子变量,再对原子变量进行操作时,不会被打断,故而可起到保护资源的目的。
2.自旋锁(spinlock)
用自旋锁保护敏感的代码段,使它在执行该代码段期间不被打断。
A.定义和初始化自旋锁
spinlock_t lock; lock=SPIN_LOCK_UNLOCK; //初始化自旋锁
B.锁定自旋锁
spin_lock(lock); //锁定自旋锁
C.受保护的代码块
访问临界资源的代码块
D.释放自旋锁
spin_unlock(lock); //释放自旋锁
PS:自旋锁不能用于递归的代码块,否则会造成死锁。
3.信号量(semaphore)
信号量是保护临界资源的另一种方式,与自旋锁不同的是,信号量没有释放时,进程将进入休眠状态,而不是忙则等待(自旋锁)。
A.信号量结构体如下
struct semaphore { spinlock_t lock; unsigned int count; struct list_head wait_list;};
count变量表示信号量的状态,可能取以下三种值:
=0:wait_list中没有等待的进程,并且该信号量不能被其他进程使用。
>0:这个信号量空闲,其他进程可以获取这个信号量。
<0:这个信号的等待队列不为空(至少有一个),它们再等待信号量释放。
wait_list:表示正在等待的队列,它是一个表示因为等待该信号量而睡眠的的进程链表。
B.定义和初始化
struct semaphore sema;init_MUTEX(sema); //初始化为互斥信号量或者sema_init(sema,3); //初始化普通信号量
C.锁定信号量
down(&sema);或者down_interruptible(&sema);
D.释放信号量
up(&sema);
4.完成量(completion)
完成量类似于信号量,它的目的是告诉线程某个事情已经发生了,线程通信时,使用完成量比较有效率。
A.完成量结构体
struct completion{ unsigned int done; //为0时会将拥有完成量的线程///置于等待状态,大于0时表示不用等待 wait_queue_head_t wait; //等待队列 }
B.定义并初始化完成量
struct completion com;init_completion(&com); //初始化完成量
C.等待完成量
wait_for_completion(&com);
D.释放完成量
complete(&com); //释放一个完成量,激活一个等待完成量的线程complete_all(&com); //激活所有等待该完成量的线程
1.原子操作
利用原子变量,再对原子变量进行操作时,不会被打断,故而可起到保护资源的目的。
2.自旋锁(spinlock)
用自旋锁保护敏感的代码段,使它在执行该代码段期间不被打断。
A.定义和初始化自旋锁
spinlock_t lock; lock=SPIN_LOCK_UNLOCK; //初始化自旋锁
B.锁定自旋锁
spin_lock(lock); //锁定自旋锁
C.受保护的代码块
访问临界资源的代码块
D.释放自旋锁
spin_unlock(lock); //释放自旋锁
PS:自旋锁不能用于递归的代码块,否则会造成死锁。
3.信号量(semaphore)
信号量是保护临界资源的另一种方式,与自旋锁不同的是,信号量没有释放时,进程将进入休眠状态,而不是忙则等待(自旋锁)。
A.信号量结构体如下
struct semaphore { spinlock_t lock; unsigned int count; struct list_head wait_list;};
count变量表示信号量的状态,可能取以下三种值:
=0:wait_list中没有等待的进程,并且该信号量不能被其他进程使用。
>0:这个信号量空闲,其他进程可以获取这个信号量。
<0:这个信号的等待队列不为空(至少有一个),它们再等待信号量释放。
wait_list:表示正在等待的队列,它是一个表示因为等待该信号量而睡眠的的进程链表。
B.定义和初始化
struct semaphore sema;init_MUTEX(sema); //初始化为互斥信号量或者sema_init(sema,3); //初始化普通信号量
C.锁定信号量
down(&sema);或者down_interruptible(&sema);
D.释放信号量
up(&sema);
4.完成量(completion)
完成量类似于信号量,它的目的是告诉线程某个事情已经发生了,线程通信时,使用完成量比较有效率。
A.完成量结构体
struct completion{ unsigned int done; //为0时会将拥有完成量的线程///置于等待状态,大于0时表示不用等待 wait_queue_head_t wait; //等待队列 }
B.定义并初始化完成量
struct completion com;init_completion(&com); //初始化完成量
C.等待完成量
wait_for_completion(&com);
D.释放完成量
complete(&com); //释放一个完成量,激活一个等待完成量的线程complete_all(&com); //激活所有等待该完成量的线程