信号量实现的机制
信号量是一种睡眠锁。它是实现同步操作,防止竟态的方式之一。任何进程在对共享数据进行读写操作之前必须获得用来保护共享数据的信号量,否则不能供访问权限,信号量会把这个访问进程放进一个等待队列中(这个等待队列是在信号量初始化过程中被初始化的),然后让其进入睡眠状态。这是处理器重新调度,去执行其他进程的操作。保护共享数据的信号量被释放,被这个信号量放进等待队列的进程会被激活,获得该信号量,然后对共享数据进行访问。
信号量的实现函数
static inline void sema_init(struct semaphore *sem, int val)
{
atomic_set(&sem->count, val);
sem->sleepers = 0;
init_waitqueue_head(&sem->wait);
}
Sema_init()函数初始化信号量,参数val表示可以同步访问共享资源的进程数目。
static inline void init_MUTEX(struct semaphore *sem)
{
sema_init(sem, 1);
}
Init_MUTEX()函数初始化信号量为互斥量。 互斥量为信号量的特例。只允许连个进程同步访问共享资源。
static inline void init_MUTEX_LOCKED(struct semaphore *sem)
{
sema_init(sem, 0);
}
Init_MUTEX_LOCKED()函数用来初始化信号量为互斥量,并初始化互斥量为被获得状态。
static inline void down(struct semaphore * sem)
{
might_sleep();
__down_op(sem, __down_failed);
}
Down()函数用来获取信号量,如果信号量值大于或等于0,获取信号量,否则进入睡眠状态,睡眠状态不可唤醒。
static inline int down_interruptible (struct semaphore * sem)
{
might_sleep();
return __down_op_ret(sem, __down_interruptible_failed);
}
Down_interruptible()函数用来获取信号量,如果信号量大于或等于0,获取信号量,否则进入睡眠状态,等待信号量被释放后,激活该进程。
static inline int down_trylock(struct semaphore *sem)
{
return __down_op_ret(sem, __down_trylock_failed);
}
Down_trylock()函数试图获取信号量,如果信号量已被其他进程获取,则立刻返回非零值。
static inline void up(struct semaphore * sem)
{
__up_op(sem, __up_wakeup);
}
Up()函数释放信号量, 激活等待队列中进程。
信号量的使用格式 from 《linux内核设计与实现》
/* 定义并声明一个信号量, 用于信号量计数 */
Static DECLARE_MUTEX(mr_sem);
/*试图获取信号量 ……*/
If(down+_interruptible(&mr_sem))
{
/* 信号被接收,信号量还未获取 */
}
/* 临界区…… */
/* 释放给定的信号量 */
Up(&mr_sem);
本文深入解析了信号量作为同步机制的工作原理,介绍了信号量的初始化、获取与释放等关键操作函数,并通过示例展示了信号量在Linux内核中的具体应用。

876

被折叠的 条评论
为什么被折叠?



