函数read_seqbegin():读者访问共享资源前需要调用该函数,该函数实际并没有进行获得和释放锁的操作,它只是返回顺序锁sl的当前顺序号。如果顺序锁sl正被某一写者持有,则它一直等待直到锁sl被释放,并返回锁的当前顺序号。
read_seqbegin文件包含
#include <linux/seqlock.h>
read_seqbegin函数定义
在内核源码中的位置:linux-3.19.3/include/linux/seqlock.h
函数定义格式:
static inline unsigned read_seqbegin(const seqlock_t *sl)
read_seqbegin输入参数说明
sl
:指向顺序锁结构体的指针。关于顺序锁结构体seqlock _t的定义及顺序锁的概念参考极客笔记中宏seqlock_init()的分析。
read_seqbegin返回参数说明
- 函数
read_seqbegin()
返回一个无符号整型值,它表示顺序锁sl的当前顺序号。
read_seqbegin实例解析
编写测试文件:read_seqbegin.c
头文件及全局变量声明如下:
#include <linux/seqlock.h>
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int __init read_seqbegin_init(void);
static void __exit read_seqbegin_exit(void);
seqlock_t seqlock ;
模块初始化函数:
int __init read_seqbegin_init(void)
{
int ret;
seqlock_init( &seqlock ); //初始化顺序锁
/*一下两行输出顺序锁中自旋锁字段值和顺序锁当前的顺序号*/
printk("after seqlock_init, sequence: %d\n\n", seqlock.seqcount.sequence);
write_seqlock( &seqlock ); //写者申请顺序锁
printk("after write_seqlock, sequence: %d\n\n", seqlock.seqcount.sequence);
write_sequnlock( &seqlock ); //写者释放顺序锁
printk("after write_sequnlock, sequence: %d\n\n", seqlock.seqcount.sequence);
ret = read_seqbegin( &seqlock ); //读者访问共享资源前需要调用该函数
printk("ret = %d\n", ret );
printk("after read_seqbegin, seqlock.sequence: %d\n\n", seqlock.seqcount.sequence);
return 0;
}
模块退出函数:
void __exit read_seqbegin_exit(void)
{
printk("exit! \n");
}
模块初始化及退出函数调用:
module_init(read_seqbegin_init);
module_exit(read_seqbegin_exit);
实例运行结果及分析:
首先编译模块,执行命令insmod read_seqbegin.ko插入模块,然后执行命令dmesg -c,会出现如图所示的结果。
结果分析:
测试程序中调用了宏seqlock_init()和函数write_seqlock()、函数write_sequnlock(),其功能参考极客笔记中关于它们的分析。
从输出信息可以看到,调用了函数read_seqbegin()之后,顺序锁的两个字段的值均未改变,这说明该函数并没有执行任何申请和释放锁的操作,它只返回顺序锁seqlock的当前顺序号ret = 2。
另外,函数read_seqbegin()在顺序锁被释放后返回,如果顺序锁正被某一写者持有,则它一直等待直到锁被释放,然后返回锁的当前顺序号。