Linux信号量操作次数的探究
来源:互联网 发布:数据挖掘的作用 编辑:程序博客网 时间:2024/06/07 17:50
需求源于项目中一部分设计的代码。struct semaphore类型的信号量,使用up()进行释放,down_interruptible()和down()获得指定信号量(前者中,若该信号量已争用则进入可中断睡眠,后者进入不可中断睡眠)。
理想中的流程应该是线程调用down()阻塞一个信号量,等待另一个线程调用up()释放,从而实现同步。但如果另一个线程使用up()释放多次,会有怎样的结果呢?LKD上没有进行详细的解释,我使用一个简单的测试程序,其中的核心代码如下:
/* A线程,释放信号量 */
while(!kthread_should_stop())
{
up(&my_sem);
set_current_state(TASK_INTERRUPTIBLE);
SLEEP_MILLI_SEC(2000); //睡眠宏,以ms为单位
}
/* B线程,获得信号量 */
while(!kthread_should_stop())
{
down_interruptible(&my_sem);
struct timeval t;
do_gettimeofday(&t);
printk("Time is:%ld %ld\n", t.tv_sec, t.tv_usec);
}
这时的行为是:每隔2s打印一次时间。
当把A线程改为一次释放两次时,输出发生了改变:
[ 7357.645663] Time is: 1342870729 491558
[ 7357.645667] Time is: 1342870729 491574
[ 7359.646921] Time is: 1342870731 492824
[ 7359.646925] Time is: 1342870731 492830
[ 7361.644350] Time is: 1342870733 490254
[ 7361.644353] Time is: 1342870733 490259
[ 7363.644699] Time is: 1342870735 490602
[ 7363.644703] Time is: 1342870735 490609
可以看出,A线程每2秒释放两次,结果使得B线程每2秒打印两次,两次打印相当于无间隔。
继续修改,每2秒A线程up()操作3次然后睡眠,B线程一次循环down_interruptible()操作2次后进行输出,下面是最初一部分的内核输出。
[ 7983.526972] Time is: 1342871355 372854
[ 7985.524609] Time is: 1342871357 370512
[ 7985.524654] Time is: 1342871357 370559
[ 7987.524217] Time is: 1342871359 370119
[ 7989.524138] Time is: 1342871361 370041
[ 7989.524142] Time is: 1342871361 370047
[ 7991.524454] Time is: 1342871363 370357
[ 7993.525012] Time is: 1342871365 370914
[ 7993.525017] Time is: 1342871365 370923
[ 7995.524760] Time is: 1342871367 370663
分析如下:A第一次释放了3个资源,B攒够2个进行第一次输出,多余的1个虽已申请,但还差1个;2秒后A又释放了3个,B一下子攒够了4个,进行两次连续的输出。此后如此循环。
可以看出,这种信号量不是非0即1的二值信号量,如果释放过多而又不能及时消耗,很有可能造成数据溢出和宕机。
- Linux信号量操作次数的探究
- linux的信号量操作
- linux下的信号量操作示例
- Linux信号量PV操作
- LINUX 信号量操作
- Linux信号量PV操作
- linux中的信号量操作
- 进程的信号量操作
- 信号量操作的包装
- 信号量的PV操作
- 9信号量的操作
- 【Linux基础】信号量基本操作
- Linux信号量常用操作表
- 操作系统中关于信号量操作的代码示例(Linux + windows)
- 操作系统中关于信号量操作的代码示例(Linux + windows)
- <linux进程>system-V信号量的基本操作
- Linux信号量的用法
- Linux的信号量
- 通过对inode的修改对文件操作进行扩充
- 再读Socket编程——《UNIX网络编程(卷一)》学习点滴
- 内核线程的创建、使用和退出;关于延时宏的补充说明
- 内核线程优先级的设置
- EXPORT_SYMBOL的使用并以使用do_adjtimex调节内核tick_length(滴答长度)为例的说明
- Linux信号量操作次数的探究
- 交叉编译生成模块的makefile写法
- ARM架构下添加系统调用(与32位x86区别)
- 利用隐藏神经元解决异或问题的小型示例程序
- 红黑树的学习笔记
- B-树的学习笔记与C实现
- 稀疏图上的Johnson算法
- VC维含义的个人理解
- Linux下Matlab的安装和中文显示支持