先看进程间的互斥。在linux内核中主要通过semaphore机制和spin_lock机制实现。主要的区别是在semaphore机制中,进不了临界区时会进行进程的切换,而spin_lock刚执行忙等在SMP中)。
先看内核中的semaphore机制。前提是对引用计数count增减的原子性操作。内核用ato
mic_t的数据结构和在它上面的一系列操作如atomic_add()、atomic_sub()等等实现。定义在atomic.h中)
semaphone机制主要通过up()和down()两个操作实现。
semaphone的结构为
structsemaphore {
atomic_t count;
intsleepers;
wait_queue_head_t wait;
};
相应的down()函数为
staticinlinevoiddown(structsemaphore*sem)
{
/* 1 */sem->count--; //为原子操作
if(sem->count<0)
{
structtask_struct *tsk = current;
DECLARE_WAITQUEUE(wait, tsk);
tsk->state = TASK_UNINTERRUPTIBLE;
add_wait_queue_exclusive(&sem->wait, &wait);
spin_lock_irq(&semaphore_lock);
/* 2 */ sem->sleepers++;
for(;;) {
intsleepers = sem->sleepers;
/*
* Add "everybody else" into it. They aren't
* playing, because we own the spinlock.
*/
/* 3 */ if (!atomic_add_negative(sleepers - 1, &sem->count)) {
/* 4 */ sem->sleepers = 0; //这时sem->count=0
break;
}
/* 4 */ sem->sleepers = 1; /* us - see -1 above */ // 这时sem
->count
=-1
spin_unlock_irq(&semaphore_lock);
schedule();
tsk->state = TASK_UNINTERRUPTIBLE;
spin_lock_irq(&semaphore_lock);
}
spin_unlock_irq(&semaphore_lock);
remove_wait_queue(&sem->wait, &wait);
tsk->state = TASK_RUNNING;
wake_up(&sem->wait);
}
}
相应的up()函数为
voidup(structsemaphore*sem)
{
sem->count++; //为原子操作
if(sem->count<=0)
{
//唤醒等待队列中的一个符合条件的进程因为每个进程都加了TASK_EXCLUSIVE标志)
。
};
假设开始时,count=1;sleepers=0
http://www.dengb.com/Linuxjc/601679.htmlwww.dengb.comtruehttp://www.dengb.com/Linuxjc/601679.htmlTechArticle先看进程间的互斥。在 linux内核 中主要通过semaphore机制和spin_lock机制实现。主要的区别是在semaphore机制中,进不了临界区时会进行进程的切...