linux内核学习(19)内核编程基本功之内核同步与互斥锁mutex

  • Post author:
  • Post category:linux



Pro-II、内核同步与互斥锁:


1、理解互斥锁?


互斥锁的使用也是保持内核临界区的同步的,互斥锁可以说源于信号量,信号量设置计数器可以容许n个进程并发的访问临界区,而互斥锁不行,只能容许每次一个进程访问,也就是计数器值为1的信号量,可以这么理解。互斥锁和自旋锁有不同(显然的),互斥锁在中断处理程序中和可延迟函数中都不能使用,因为它是可以睡眠的,只能在进程上下文或者软中断上下文才能使用。




2、如何实现互斥锁?




2-1、结构体:




2-1-1、mutex结构体:


struct mutex {


/* 1: unlocked, 0: locked, negative: locked, possible waiters */


atomic_t count;


spinlock_t wait_lock;


struct list_head wait_list;


//我们关心上面三个变量


#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)


struct thread_info *owner;


#endif


#ifdef CONFIG_DEBUG_MUTEXES


const char *name;


void *magic;


#endif


#ifdef CONFIG_DEBUG_LOCK_ALLOC


struct lockdep_map dep_map;


#endif


};




2-1-2、mutex_waiter结构体:


struct mutex_waiter {


struct list_head list;


struct task_struct *task;


#ifdef CONFIG_DEBUG_MUTEXES


void *magic;


#endif


};




2-2、方法:




2-2-1、初始化:




# define

mutex_init

(mutex) /


do { /


static struct lock_class_key __key; /


/



__mutex_init

((mutex), #mutex, &__key); /


} while (0)




void


__mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key)


{


atomic_set(&lock->count, 1); //设置计数器


spin_lock_init(&lock->wait_lock); //初始化自旋锁


INIT_LIST_HEAD(&lock->wait_list); //初始化等待队列


mutex_clear_owner(lock);




debug_mutex_init(lock, name, key);


}




2-2-2、锁住:




void __sched mutex_lock(struct mutex *lock)


{


might_sleep();


/*


* The locking fastpath is the 1->0 transition from


* ‘unlocked’ into ‘locked’ state.


*/



__mutex_fastpath_lock

(&lock->count,

__mutex_lock_slowpath

);


mutex_set_owner(lock);



版权声明:本文为cug_fish_2009原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。