FreeBSD5.0内核---锁机制

2009-05-13 06:36:48来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

在FreeBSD5.0中,有很多类型的锁:互斥体(struct mtx)、共享/独占锁(struct sx)、lockmgr锁(struct lock)、条件变量(struct cv)和信号量(struct sema)。本文将探讨这些锁机制的含义、应用和实现。另外,有一种文件锁(struct lockf)用于文件字段的保护,嵌在inode结构中使用,是属于另外的范畴,这里不做说明,有兴趣可以参考flock(2)和VOP_ADVLOCK(9)。
1 基本锁机制
struct lock_class {
const char *lc_name;
u_int lc_flags;
};
本文讨论的锁机制,任何一种类型都直接/间接的包含该结构。每一个锁都有一个类(lock_class),该类描述了某个锁类(lc_name)和基本特性(lc_flags)。
其中,lc_flags的宏定义:LC_SLEEPLOCK是普通锁;LC_SPINLOCK是自旋锁;LC_SLEEPABLE说明可以在对该锁加锁的情况下,休眠;LC_RECURSABLE说明该锁是否支持递归;LC_UPGRADABLE说明该锁支持从共享锁变为独占锁,抑或相反。
目前,系统支持如下的lock_class:
struct lock_class lock_class_mtx_sleep = {
"sleep mutex",
LC_SLEEPLOCK | LC_RECURSABLE
};
struct lock_class lock_class_mtx_spin = {
"spin mutex",
LC_SPINLOCK | LC_RECURSABLE
};
struct lock_class lock_class_sx = {
"sx",
LC_SLEEPLOCK | LC_SLEEPABLE | LC_RECURSABLE | LC_UPGRADABLE
};
前两个说明了互斥体支持的两个类(MTX_DEF、MTX_SPIN);后一个说明了共享/独占锁的类。
struct lock_object {
struct lock_class *lo_class;
const char *lo_name; /* Individual lock name. */
const char *lo_type; /* General lock type. */
u_int lo_flags;
TAILQ_ENTRY(lock_object) lo_list; /* List of all locks in system. */
struct witness *lo_witness;
};
用于存储一个具体锁的数据结构,lo_name是单个具体锁的名字;如果在锁初始化时指定了类型描述的字符串,则赋给lo_type,否则lo_type的值和lo_name一样。
成员lo_flags的值,及其说明如下:
#define LO_CLASSFLAGS 0x0000ffff /* Class specific flags. */
#define LO_INITIALIZED 0x00010000 /* Lock has been initialized. */
#define LO_WITNESS 0x00020000 /* Should witness monitor this lock. */
#define LO_QUIET 0x00040000 /* Don't log locking operations. */
#define LO_RECURSABLE 0x00080000 /* Lock may recurse. */
#define LO_SLEEPABLE 0x00100000 /* Lock may be held while sleeping. */
#define LO_UPGRADABLE 0x00200000 /* Lock may be upgraded/downgraded. */
#define LO_DUPOK 0x00400000 /* Don't check for duplicate acquires */
余下两个成员,lo_list用于加入全局all_locks链表中,lo_witness用于指向witness数据结构。这两个成员的作用是用于witness模块,跟踪锁的获得、释放。这个部分需要参考witness(9)。
本节介绍了FreeBSD锁机制的最基本的结构和意义,下面介绍各种锁机制的基本含义。
2互斥体(Mutex)
FreeBSD5.0进程同步控制的基本和主要方法是Mutex。在设计时,主要有如下考虑:
Ø 申请和释放一个无争议的互斥体应该尽可能的简单。
Ø 互斥体的数据结构应该有足够的信息和存储空间来支持优先级的继承。
Ø 一个进程应该可以递归地使用某一个互斥体(比如最常用的全局互斥体Giant)。
根据Mutex阻塞时,是否做上下文切换,可以分为两类:MTX_DEF(做切换)和MTX_SPIN(不做切换)。

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Excel单元格内按时间规律显示名言警句 (转贴)

下一篇:Web 状态机一招鲜, 第一部、Python 状态机入门