互斥锁_zzhere2007

来源:互联网 发布:御彩轩计划软件群 编辑:程序博客网 时间:2024/06/06 10:50
简介:
互斥体实现了“互相排斥”(mutual exclusion)同步的简单形式(所以名为互斥体(mutex))。互斥体禁止多个线程同时进入受保护的代码“临界区”(critical section)。因此,在任意时刻,只有一个线程被允许进入这样的代码保护区。
任何线程在进入临界区之前,必须获取(acquire)与此区域相关联的互斥体的所有权。如果已有另一线程拥有了临界区的互斥体,其他线程就不能再进入其中。这些线程必须等待,直到当前的属主线程释放(release)该互斥体。
什么时候需要使用互斥体呢?互斥体用于保护共享的易变代码,也就是,全局或静态数据。这样的数据必须通过互斥体进行保护,以防止它们在多个线程同时访问时损坏


Linux 2.6.26中mutex的定义:struct mutex {        /* 1: unlocked, 0: locked, negative: locked, possible waiters */        atomic_t                  count;        spinlock_t                wait_lock;        struct list_head          wait_list;#ifdef CONFIG_DEBUG_MUTEXES        struct thread_info        *owner;        const char                *name;        void                      *magic;#endif#ifdef CONFIG_DEBUG_LOCK_ALLOC        struct lockdep_map         dep_map;#endif};

使用:

1  如果要定义一个静态mutex型变量,应该使用DEFINE_MUTEX2  如果在程序运行期要初始化一个mutex变量,可以使用mutex_init(mutex),mutex_init是个宏,在该宏定义的内部,会调用__mutex_init函数。3  mutex上的P,V操作:                                        void mutex_lock(struct mutex *lock)                                       void __sched mutex_unlock(struct mutex *lock)


原理:
对比前面的struct semaphore,struct mutex除了增加了几个作为debug用途的成员变量外,和semaphore几乎长得一样。但是mutex的引入主要是为了提供互斥机制,以避免多个进程同时在一个临界区中运行。
#define mutex_init(mutex)                                                   \do {                                                                        \        static struct lock_class_key __key;                                 \                                                                            \         __mutex_init((mutex), #mutex, &__key);                              \} while (0)__mutex_init定义如下: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);        debug_mutex_init(lock, name, key);}

     从__mutex_init的定义可以看出,在使用mutex_init宏来初始化一个mutex变量时,应该使用mutex的指针型。
从原理上讲,mutex实际上是count=1情况下的semaphore,所以其PV操作应该和semaphore是一样的。但是在实际的Linux代码上,出于性能优化的角度,并非只是单纯的重用down_interruptible和up的代码。以ARM平台的mutex_lock为例,实际上是将mutex_lock分成两部分实现:fast path和slow path,主要是基于这样一个事实:在绝大多数情况下,试图获得互斥体的代码总是可以成功获得。所以Linux的代码针对这一事实用ARM V6上的LDREX和STREX指令来实现fast path以期获得最佳的执行性能。