歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux內核

Linux內核同步機制之信號量與鎖

Linux內核同步控制方法有很多,信號量、鎖、原子量、RCU等等,不同的實現方法應用於不同的環境來提高操作系統效率。首先,看看我們最熟悉的兩種機制——信號量、鎖。

一、信號量 

首先還是看看內核中是怎麼實現的,內核中用struct semaphore數據結構表示信號量(<linux/semphone.h>中):

  1. struct semaphore {  
  2.     spinlock_t      lock;  
  3.     unsigned int        count;  
  4.     struct list_head    wait_list;  
  5. };  

其中lock為自旋鎖,放到這裡是為了保護count的原子增減,無符號數count為我們競爭的信號量(PV操作的核心),wait_list為等待此信號量的進程鏈表。

初始化:

對於這一類工具類使用較多的機制,包括用於同步互斥的信號量、鎖、completion,用於進程等待的等待隊列、用於Per-CPU的變量等等,內核都提供了兩種初始化方法,靜態與動態方式。 

1)      靜態初始化,實現代碼如下:

  1. #define __SEMAPHORE_INITIALIZER(name, n)                \   
  2. {                                   \  
  3.     .lock       = __SPIN_LOCK_UNLOCKED((name).lock),        \  
  4.     .count      = n,                        \  
  5.     .wait_list  = LIST_HEAD_INIT((name).wait_list),     \  
  6. }  
  7.   
  8. #define DECLARE_MUTEX(name) \   
  9.     struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1)  

可以看到,這種初始化使我們在編程的時候直接用一條語句DECLARE_MUTEX(name);就可以完成申明與初始化,另一種下面要說的動態初始化方式申請與初始化分離。

2)      我們看到,靜態初始化時信號量的count值初始化為1,當我們需要初始化為0時需要用動態初始化方法。

  1. #define init_MUTEX(sem)     sema_init(sem, 1)   
  2. #define init_MUTEX_LOCKED(sem)  sema_init(sem, 0)   
  3.   
  4. static inline void sema_init(struct semaphore *sem, int val)  
  5. {  
  6.     static struct lock_class_key __key;  
  7.     *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val);  
  8.     lockdep_init_map(&sem->lock.dep_map, "semaphore->lock", &__key, 0);  
  9. }  
Copyright © Linux教程網 All Rights Reserved