linux互斥锁简介(内核态)
linux-dash
A beautiful web dashboard for Linux
项目地址:https://gitcode.com/gh_mirrors/li/linux-dash
免费下载资源
·
一、什么是互斥锁
1、概念
互斥锁(Mutex)是在原子操作API的基础上实现的信号量行为。互斥锁不能进行递归锁定或解锁,能用于交互上下文但是不能用于中断上下文,同一时间只能有一个任务持有互斥锁,而且只有这个任务可以对互斥锁进行解锁。当无法获取锁时,线程进入睡眠等待状态。
互斥锁是信号量的特例。信号量的初始值表示有多少个任务可以同时访问共享资源,如果初始值为1,表示只有1个任务可以访问,信号量变成互斥锁(Mutex)。但是互斥锁和信号量又有所区别,互斥锁的加锁和解锁必须在同一线程里对应使用,所以互斥锁只能用于线程的互斥;信号量可以由一个线程释放,另一个线程得到,所以信号量可以用于线程的同步。
2、数据结构
1、atomic_t count;
指示互斥锁的状态:1 没有上锁,可以获得;0 被锁定,不能获得。初始化为没有上锁。
2、spinlock_t wait_lock;
等待获取互斥锁中使用的自旋锁。在获取互斥锁的过程中,操作会在自旋锁的保护中进行。初始化为为锁定。
3、struct list_head wait_list;
等待互斥锁的进程队列。
二、如何使用互斥锁
1、初始化
mutex_init(&mutex); //动态初始化互斥锁
DEFINE_MUTEX(mutexname); //静态定义和初始化互斥锁
2、上锁
void mutex_lock(struct mutex *lock);
无法获得锁时,睡眠等待,不会被信号中断。
int mutex_trylock(struct mutex *lock);
此函数是 mutex_lock()的非阻塞版本,成功返回1,失败返回0。
int mutex_lock_interruptible(struct mutex *lock);
和mutex_lock()一样,也是获取互斥锁。在获得了互斥锁或进入睡眠直到获得互斥锁之后会返回0。如果在等待获取锁的时候进入睡眠状态收到一个信号(被信号打断睡眠),则返回_EINIR。
3、解锁
void mutex_unlock(struct mutex *lock);
三、什么时候使用互斥锁
1、互斥锁和信号量比较
a、互斥锁功能上基本与二元信号量一样,但是互斥锁占用空间比信号量小,运行效率比信号量高。所以,如果要用于线程间的互斥,优先选择互斥锁。
2、互斥锁和自旋锁比较
a、互斥锁在无法得到资源时,内核线程会进入睡眠阻塞状态,而自旋锁处于忙等待状态。因此,如果资源被占用的时间较长,使用互斥锁较好,因为可让CPU调度去做其它进程的工作。
b、如果被保护资源需要睡眠的话,那么只能使用互斥锁或者信号量,不能使用自旋锁。而互斥锁的效率又比信号量高,所以这时候最佳选择是互斥锁。
c、中断里面不能使用互斥锁,因为互斥锁在获取不到锁的情况下会进入睡眠,而中断是不能睡眠的。
1、概念
互斥锁(Mutex)是在原子操作API的基础上实现的信号量行为。互斥锁不能进行递归锁定或解锁,能用于交互上下文但是不能用于中断上下文,同一时间只能有一个任务持有互斥锁,而且只有这个任务可以对互斥锁进行解锁。当无法获取锁时,线程进入睡眠等待状态。
互斥锁是信号量的特例。信号量的初始值表示有多少个任务可以同时访问共享资源,如果初始值为1,表示只有1个任务可以访问,信号量变成互斥锁(Mutex)。但是互斥锁和信号量又有所区别,互斥锁的加锁和解锁必须在同一线程里对应使用,所以互斥锁只能用于线程的互斥;信号量可以由一个线程释放,另一个线程得到,所以信号量可以用于线程的同步。
2、数据结构
struct mutex {
/* 1: unlocked, 0: locked, negative: locked, possible waiters */
atomic_t count;
spinlock_t wait_lock;
struct list_head wait_list;
#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_MUTEX_SPIN_ON_OWNER)
struct task_struct *owner;
#endif
#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
struct optimistic_spin_queue osq; /* Spinner MCS lock */
#endif
#ifdef CONFIG_DEBUG_MUTEXES
void *magic;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
};
结构体成员说明:
1、atomic_t count;
指示互斥锁的状态:1 没有上锁,可以获得;0 被锁定,不能获得。初始化为没有上锁。
2、spinlock_t wait_lock;
等待获取互斥锁中使用的自旋锁。在获取互斥锁的过程中,操作会在自旋锁的保护中进行。初始化为为锁定。
3、struct list_head wait_list;
等待互斥锁的进程队列。
二、如何使用互斥锁
1、初始化
mutex_init(&mutex); //动态初始化互斥锁
DEFINE_MUTEX(mutexname); //静态定义和初始化互斥锁
2、上锁
void mutex_lock(struct mutex *lock);
无法获得锁时,睡眠等待,不会被信号中断。
int mutex_trylock(struct mutex *lock);
此函数是 mutex_lock()的非阻塞版本,成功返回1,失败返回0。
int mutex_lock_interruptible(struct mutex *lock);
和mutex_lock()一样,也是获取互斥锁。在获得了互斥锁或进入睡眠直到获得互斥锁之后会返回0。如果在等待获取锁的时候进入睡眠状态收到一个信号(被信号打断睡眠),则返回_EINIR。
3、解锁
void mutex_unlock(struct mutex *lock);
三、什么时候使用互斥锁
1、互斥锁和信号量比较
a、互斥锁功能上基本与二元信号量一样,但是互斥锁占用空间比信号量小,运行效率比信号量高。所以,如果要用于线程间的互斥,优先选择互斥锁。
2、互斥锁和自旋锁比较
a、互斥锁在无法得到资源时,内核线程会进入睡眠阻塞状态,而自旋锁处于忙等待状态。因此,如果资源被占用的时间较长,使用互斥锁较好,因为可让CPU调度去做其它进程的工作。
b、如果被保护资源需要睡眠的话,那么只能使用互斥锁或者信号量,不能使用自旋锁。而互斥锁的效率又比信号量高,所以这时候最佳选择是互斥锁。
c、中断里面不能使用互斥锁,因为互斥锁在获取不到锁的情况下会进入睡眠,而中断是不能睡眠的。
GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e
added ecosystem file for PM2 4 年前
5def40a3
Add host customization support for the NodeJS version 4 年前
更多推荐
已为社区贡献5条内容
所有评论(0)