Linux内核学习笔记七——内核同步机制和实现方式(2)
- UID
- 1029342
- 性别
- 男
|
Linux内核学习笔记七——内核同步机制和实现方式(2)
声明信号量:
信号量数据结构:/* Please don't access any members of this structure directly */struct semaphore { raw_spinlock_t lock; unsigned int count; struct list_head wait_list;};
静态声明信号量:
//声明可用数量为1信号量#define DEFINE_SEMAPHORE(name) \ struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1)//声明可用数量为n的信号量#define __SEMAPHORE_INITIALIZER(name, n) \{ \ .lock = __RAW_SPIN_LOCK_UNLOCKED((name).lock), \ .count = n, \ .wait_list = LIST_HEAD_INIT((name).wait_list), \}
动态声明信号量:
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);}
使用信号量:
//初始化定义信号量 struct semaphore driver_lock; sema_init(&driver_lock, 1); //获取信号量 if (down_interruptible(&driver_lock)) return -EINTR; //执行临界区 …… //释放信号量 up(&driver_lock);
自旋锁与信号量对比:
需求 使用锁
低开销加锁 : 优先使用自旋锁
短期锁定 : 优先使用自旋锁
长期锁定 : 优先使用信号量
中断上下文加锁 : 使用自旋锁
持有锁需要睡眠 : 使用信号量
四 完成变量
完成变量:如果在内核中一个任务需要发出信号通知另一个任务发生了某个特定事件,
使用完成变量去唤醒在等待的任务,使两个任务得以同步。信号量的简易方法。
数据结构:
struct completion { unsigned int done; wait_queue_head_t wait;};
完成变量声明:
动态:#define COMPLETION_INITIALIZER(work) \ { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) }静态: static inline void init_completion(struct completion *x){ x->done = 0; init_waitqueue_head(&x->wait);}
完成变量使用:
//等待制定的完成变量void __sched wait_for_completion(struct completion *x)//发信号唤醒等待的任务void complete(struct completion *x) |
|
|
|
|
|