宏init_rwsem()的功能是初始化读写信号量,将信号量的count字段设置为0, wait_lock自旋锁设置为未锁,将等待进程的链表wait_list置为空链表。关于读写信号量结构体rw_semaphore的定义参考极客笔记的介绍。
init_rwsem文件包含
#include <linux/rwsem.h>
init_rwsem宏定义
在内核源码中的位置:linux-3.19.3/include/linux/rwsem.h
宏定义格式:
#define init_rwsem(sem) \
do { \
static struct lock_class_key __key; \
__init_rwsem((sem), #sem, &__key); \
} while (0)
init_rwsem输入参数说明
sem
:表示待初始化的读写信号量,该参数一般为指针。其中,读写信号量结构体rw_semaphore在内核文件linux-3.19.3/include/linux/rwsem.h中定义:
struct rw_semaphore {
long count;
struct list_head wait_list;
raw_spinlock_t wait_lock;
#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
struct optimistic_spin_queue osq;
struct task_struct * owner;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
};
- 字段
count
:它实际上是两个16位的计数器,高16位的值表示等待的写者进程的总数,低16位的值表示已获取信号量的读者或者写者进程的总数。 - 字段
wait_lock
:自旋锁,与读写信号量相对应,用来保护rw_semaphore结构。 - 字段
wait_list
:等待队列。
读写信号量是对信号量的改进。它允许多个读者读,而最多只能有一个写者。如果一个读写信号量没有被写者持有或者没有写者在等待获取该信号量,则任何读者都可以成功获得该读写信号量,否则,读者将被挂起直到写者释放该信号量。如果一个信号量没有被读者或写者持有或者当前没有写者在等待获取该信号量,则写者可以成功获取该信号量,否则,写者将被挂起直到写者释放该信号量。从中可以看出,写者获取读写信号量时是排他性的,具有独占性。
init_rwsem返回参数说明
- 该宏没有返回值。
init_rwsem实例解析
编写测试文件:init_rwsem.c
头文件及全局变量声明如下:
#include <linux/rwsem.h>
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int __init init_rwsem_init(void);
static void __exit init_rwsem_exit(void);
struct rw_semaphore rwsem ;
模块初始化函数:
int __init init_rwsem_init(void)
{
init_rwsem( &rwsem ); //读写信号量初始化
/* 输出读写信号量中的字段信息*/
printk("after init_rwsem, count: %d\n", rwsem.count);
return 0;
}
模块退出函数:
void __exit init_rwsem_exit(void)
{
printk("exit! \n");
}
模块初始化及退出函数调用:
module_init(init_rwsem_init);
module_exit(init_rwsem_exit);
实例运行结果及分析:
首先编译模块,执行命令insmod init_rwsem.ko插入模块,然后执行命令dmesg -c,会出现如图所示的结果。
结果分析:
首先定义一个读写信号量结构体rwsem。函数init_rwsem()的功能是初始化读写信号量,将信号量的count字段设置为0。