黑客风云——风云网络
设为首页 加入收藏 我要投稿 网站地图
您现在的位置: 黑客风云 >> 黑客文章 >> 操作系统 >> LINIX UNIX >> 文章正文
[推荐]Linux内核中的同步和互斥分析报告
        ★★★
Linux内核中的同步和互斥分析报告
文章整理发布:黑客风云 文章来源:www.05112.com 更新时间:2006-11-21
 先看进程间的互斥。在linux内核中主要通过semaphore机制和spin_lock机制实现。主要的区别是在semaphore机制中,进不了临界区时会进行进程的切换,而spin_lock刚执行忙等(在SMP中)。先看内核中的semaphore机制。前提是对引用计数count增减的原子性操作。内核用atomic_t的数据结构和在它上面的一系列操作如atomic_add()、atomic_sub()等等实现。(定义在atomic.h中)semaphone机制主要通过up()和down()两个操作实现。semaphone的结构为:

struct semaphore 
{ 
atomic_t count; 
int sleepers; 
wait_queue_head_t wait; 
};

  相应的down()函数为:

static inline void down(struct semaphore*sem) 
{ 
/* 1 */sem->count--; //为原子操作 
if(sem->count<0) 
{ 
struct task_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 (;;) { 
int sleepers = 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()函数为:

void up(struct semaphore*sem) 
{ 
sem->count++; //为原子操作 
if(sem->count<=0) 
{ 
//唤醒等待队列中的一个符合条件的进程(因为每个进程都加了TASK_EXCLUSIVE标志) 
。 
};

  假设开始时,count=1;sleepers=0。当进程A执行down()时,引用计数count--,如果这时它的值大于等于0,则从down()中直接返回。如果count少于0,则A的state改为TASK_INTERRUPTIBLE后进入这个信号量的等待队列中,同时使sleepers++;然后重新计算count=sleepers - 1 + count,若这时引用计数仍小于0(一般情况下应为-1,因为count = - sleepers,不过在SMP结构中,期间别的进程可能执行了up()和down()从而使得引用计数的值可能变化),则执行进程切换。

[1] [2] [3] 下一页  

文章录入:sygbox    责任编辑:cainiaowang 
【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
Copyright @2006 黑客风云 ●业务联系:QQ 联系怪人 联系奇人 Email:给怪人发邮件 给奇人发邮件
ICP备案:冀06009886