Linux内核同步机制之信号量与锁

Linux内核同步控制方法有很多,信号量、锁、原子量、RCU等等,不同的实现方法应用于不同的环境来提高操作系统效率。首先,看看我们最熟悉的两种机制——信号量、锁。

一、信号量 

首先还是看看内核中是怎么实现的,内核中用struct semaphore数据结构表示信号量(<linux/semphone.h>中):

struct semaphore {       spinlock_t      lock;       unsigned int        count;       struct list_head    wait_list;   };  

其中lock为自旋锁,放到这里是为了保护count的原子增减,无符号数count为我们竞争的信号量(PV操作的核心),wait_list为等待此信号量的进程链表。

初始化:

对于这一类工具类使用较多的机制,包括用于同步互斥的信号量、锁、completion,用于进程等待的等待队列、用于Per-CPU的变量等等,内核都提供了两种初始化方法,静态与动态方式。 

1)      静态初始化,实现代码如下:

#define __SEMAPHORE_INITIALIZER(name, n)                \    {                                   \       .lock       = __SPIN_LOCK_UNLOCKED((name).lock),        \       .count      = n,                        \       .wait_list  = LIST_HEAD_INIT((name).wait_list),     \   }      #define DECLARE_MUTEX(name) \        struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1)  

可以看到,这种初始化使我们在编程的时候直接用一条语句DECLARE_MUTEX(name);就可以完成申明与初始化,另一种下面要说的动态初始化方式申请与初始化分离。

2)      我们看到,静态初始化时信号量的count值初始化为1,当我们需要初始化为0时需要用动态初始化方法。

#define init_MUTEX(sem)     sema_init(sem, 1)    #define init_MUTEX_LOCKED(sem)  sema_init(sem, 0)       static inline void sema_init(struct semaphore *sem, int val)   {       static struct lock_class_key __key;       *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val);       lockdep_init_map(&sem->lock.dep_map, "semaphore->lock", &__key, 0);   }  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://127.0.0.1/wyypws.html