linux 内核同步互斥技术之互斥锁
互斥锁
互斥锁只允许一个进程进入临界区,适合保护比较长的临界区,因为竞争互斥锁时进程可能睡眠和再次唤醒,代价很高。
尽管可以把二值信号量当作互斥锁使用,但是内核单独实现了互斥锁。互斥锁的定义如下:
include/linux/mutex.h
struct mutex {
? ? atomic_long_t ? ? ? owner;
? ? spinlock_t ? ? ?wait_lock;
#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
? ? struct optimistic_spin_queue osq; /* Spinner MCS lock */
#endif
? ? struct list_head ? ?wait_list;
#ifdef CONFIG_DEBUG_MUTEXES
? ? void ? ? ? ? ? ?*magic;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
? ? struct lockdep_map ?dep_map;
#endif
};
初始化静态互斥锁的方法如下:DEFINE_MUTEX(mutexname);
在运行时动态初始化互斥锁的方法如下:mutex_init(mutex);
申请互斥锁的函数如下。
(1) void mutex_lock(struct mutex *lock);
申请互斥锁,如果锁被占有,进程深度睡眠。
(2) int mutex_lock_interruptible(struct mutex *lock);
申请互斥锁,如果锁被占有,进程轻度睡眠。
(3) int mutex_lock_killable(struct mutex *lock);
申请互斥锁,如果锁被占有,进程中度睡眠。
(4) int mutex_trylock(struct mutex *lock);
申请互斥锁,如果申请成功,返回 1;如果锁被其他进程占有,那么进程不等待,返回 0。
释放互斥锁的函数如下:
void mutex_unlock(struct mutex *lock);
mutex使用注意:
1.任何时刻中只有一个任务可以持有mutex,也就是说,mutex的使用计数永远是1.
2.给mutex上锁的任务必须负责给mutex再解锁。
3.mutex不可以递归使用。
4.持有mutex的任务不可以不解锁退出。
5.mutex不能在中断或者下半部(中断上下文)使用,即使mutex_trylock()也不行。
6.mutex使用只能通过官方的API管理。
mutex使用实例:
典型的就是linux网络模块中的互斥使用的RTNL,RTNL实际为一个mutex:
static DEFINE_MUTEX(rtnl_mutex);
所以RTNL只能在进程上下文使用,其常用的接口有:rtnl_lock、rtnl_unlock、__rtnl_unlock、ASSERT_RTNL
linux中对RTNL的注释为:RTNL is used as a global lock for all changes to network configuration。也就是说各种网络配置由于关系紧密且复杂,所以在做互斥时作为一个整体来进行保护。同样也暗示了修改网络配置必须是在进程上下文中才可以,所以在消息处理的流程中去修改网络配置是非法的行为。
linux的修改网络配置的方法调用了大量的ASSERT_RTNL来确保调用者已经持有了RTNL,所以修改配置之前通常要调用rtnl_lock方法,修改后调用rtnl_unlock。但是要特别注意调用rtnl_lock的位置,当流程处理复杂时,有可能会引起RTNL的死锁,因此我们经常可以看到linux的代码中先调用rtnl_lock,然后修改一些配置,如果遇到某些情况需要睡眠一段时间,就先调用__rtnl_unlock,睡眠后再重新调用rtnl_lock,继续后面的操作。
持有RTNL的进程是可以睡眠的,在它睡眠的过程中不能有其他进程进行网络配置,如果睡眠的时间太长的话有可能会影响用户的使用。
有些数据结构的reader和writer都是运行在进程上下文,所以它们可以完全靠RTNL保护,如link_ops、net_namespace_list等
有些网络配置操作也要用RTNL互斥,如注册和注销设备
由于RTNL使用情况比较复杂,需要留意缺省已经持有RTNL的情况,避免出现死锁
1)?? ?各种网络通知回调函数,包括设备和ip地址事件通知
2)?? ?很多SIOC的配置命令
?
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!