现在的位置: 首页 > 综合 > 正文

互斥锁_zzhere2007

2018年02月07日 ⁄ 综合 ⁄ 共 1601字 ⁄ 字号 评论关闭

简介:
互斥体实现了“互相排斥”(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_MUTEX

2  如果在程序运行期要初始化一个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以期获得最佳的执行性能。

抱歉!评论已关闭.