Linux内核中的同步与互斥(1)


先看进程间的互斥。在linux内核中主要通过semaphore机制和spin_lock机制实现。主要的区别是在semaphore机制中,进不了临界区时会进行进程的切换,而spin_lock刚执行忙等在SMP中)。

先看内核中的semaphore机制。前提是对引用计数count增减的原子性操作。内核用ato

mic_t的数据结构和在它上面的一系列操作如atomic_add()、atomic_sub()等等实现。定义在atomic.h中)

semaphone机制主要通过up()和down()两个操作实现。

semaphone的结构为

  1. struct semaphore {  
  2.  
  3. atomic_t count;  
  4.  
  5. int sleepers;  
  6.  
  7. wait_queue_head_t wait;  
  8.  
  9. };  

相应的down()函数为

  1. static inline void down(struct semaphore*sem)  
  2.  
  3. {  

/* 1 */sem->count--; //为原子操作

  1. if(sem->count<0)  
  2.  
  3. {  
  4.  
  5. struct task_struct *tsk = current;  
  6.  
  7. DECLARE_WAITQUEUE(wait, tsk);  
  8.  
  9. tsk->state = TASK_UNINTERRUPTIBLE;  
  10.  
  11. add_wait_queue_exclusive(&sem->wait, &wait);  
  12.  
  13. spin_lock_irq(&semaphore_lock);  

/* 2 */ sem->sleepers++;

  1. for (;;) {  
  2.  
  3. int sleepers = sem->sleepers;  
  4.  
  5. /*  
  6.  
  7. * Add "everybody else" into it. They aren't  
  8.  
  9. * playing, because we own the spinlock.  
  10.  
  11. */ 

/* 3 */ if (!atomic_add_negative(sleepers - 1, &sem->count)) {

/* 4 */ sem->sleepers = 0; //这时sem->count=0

  1. break;  
  2.  
  3. }  

/* 4 */ sem->sleepers = 1; /* us - see -1 above */ // 这时sem

  1. ->count  
  2.  
  3. =-1  
  4.  
  5. spin_unlock_irq(&semaphore_lock);  
  6.  
  7. schedule();  
  8.  
  9. tsk->state = TASK_UNINTERRUPTIBLE;  
  10.  
  11. spin_lock_irq(&semaphore_lock);  
  12.  
  13. }  
  14.  
  15. spin_unlock_irq(&semaphore_lock);  
  16.  
  17. remove_wait_queue(&sem->wait, &wait);  
  18.  
  19. tsk->state = TASK_RUNNING;  
  20.  
  21. wake_up(&sem->wait);  
  22.  
  23. }  
  24.  
  25. }  

相应的up()函数为

  1. void up(struct semaphore*sem)  
  2.  
  3. {  

sem->count++; //为原子操作

  1. if(sem->count<=0)  
  2.  
  3. {  

//唤醒等待队列中的一个符合条件的进程因为每个进程都加了TASK_EXCLUSIVE标志)

};

假设开始时,count=1;sleepers=0


相关内容