互斥锁指代相互排斥(mutual exclusion), 它是最基本的同步形式。
在linux源代码中,mutex的定义如下:【include/linux】
简单直接的互斥锁需要满足以下严格的语义环境:
l 任意时刻拥有此互斥锁的任务不能超过一个
l 互斥锁的拥有者才能解锁
l 不允许多处解锁
l 不允许嵌套锁
l 互斥锁对象需要通过接口来初始化
l 拥有锁期间,任务不能退出
l 获得锁的内存区域不能随便被释放
在linux源代码中,mutex的定义如下:【include/linux】
简单直接的互斥锁需要满足以下严格的语义环境:
l 任意时刻拥有此互斥锁的任务不能超过一个
l 互斥锁的拥有者才能解锁
l 不允许多处解锁
l 不允许嵌套锁
l 互斥锁对象需要通过接口来初始化
l 拥有锁期间,任务不能退出
l 获得锁的内存区域不能随便被释放
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: 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
};
typedef struct { volatile int counter; } atomic_t;
互斥锁用于保护临界区(critical region),以保证任何时刻只有一个线程在执行其中的代码。保护临界区的代码的通常的轮廓大体如下:
----------------------------
mutex_lock()
临界区
mutex_unlock()
------------------------------------------
mutex_lock():获取锁,并且独占。如果当前此锁不能被获得,线程将进入睡眠。
只有获得此锁的线程才能释放此锁。
mutex_unlock():释放锁,释放由本线程先前获取的锁。不能在中断语境中应用此函数,也不能释放一个未被获取的锁。
mutex_trylock():试图获取一个锁,如果成功返回1,失败返回0.
------------------------------------------
mutex_lock():获取锁,并且独占。如果当前此锁不能被获得,线程将进入睡眠。
只有获得此锁的线程才能释放此锁。
mutex_unlock():释放锁,释放由本线程先前获取的锁。不能在中断语境中应用此函数,也不能释放一个未被获取的锁。
mutex_trylock():试图获取一个锁,如果成功返回1,失败返回0.
互斥锁用于上锁(locking)而不能用于等待(waiting)。
在线程同步的时候,有时候是需要保护一段临界区只能被一个线程执行,有时候是需要等待一些条件满足,而互斥锁不能用来完成后面这个任务。用于完成此任务的是条件变量。
在线程同步的时候,有时候是需要保护一段临界区只能被一个线程执行,有时候是需要等待一些条件满足,而互斥锁不能用来完成后面这个任务。用于完成此任务的是条件变量。