Linux信号量操作次数的探究

简介:

需求源于项目中一部分设计的代码。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的二值信号量,如果释放过多而又不能及时消耗,很有可能造成数据溢出和宕机。




本文转自五岳博客园博客,原文链接:www.cnblogs.com/wuyuegb2312/archive/2012/07/21/2602900.html,如需转载请自行联系原作者

目录
相关文章
|
4月前
|
消息中间件 Linux 开发者
Linux进程间通信秘籍:管道、消息队列、信号量,一文让你彻底解锁!
【8月更文挑战第25天】本文概述了Linux系统中常用的五种进程间通信(IPC)模式:管道、消息队列、信号量、共享内存与套接字。通过示例代码展示了每种模式的应用场景。了解这些IPC机制及其特点有助于开发者根据具体需求选择合适的通信方式,促进多进程间的高效协作。
187 3
|
5月前
|
网络协议 Linux 网络安全
入职必会-开发环境搭建39-Linux常用操作-Linux防火墙操作
在CentOS 7中,新引入了firewalld服务(防火墙),取代了CentOS 6之前的iptables服务(防火墙)。
入职必会-开发环境搭建39-Linux常用操作-Linux防火墙操作
|
5月前
|
存储 运维 Linux
Linux磁盘精准缩容:操作详解与技巧
在Linux系统管理中,有效的磁盘空间优化对于维护系统性能至关重要。本文将深入探讨如何在Linux环境下安全地进行磁盘缩容,帮助你合理调整存储资源,确保系统高效运行。跟随本篇的步骤,一起优化你的Linux系统磁盘空间!
Linux磁盘精准缩容:操作详解与技巧
|
3月前
|
Linux
linux内核 —— 读写信号量实验
linux内核 —— 读写信号量实验
|
4月前
|
开发者 API Windows
从怀旧到革新:看WinForms如何在保持向后兼容性的前提下,借助.NET新平台的力量实现自我进化与应用现代化,让经典桌面应用焕发第二春——我们的WinForms应用转型之路深度剖析
【8月更文挑战第31天】在Windows桌面应用开发中,Windows Forms(WinForms)依然是许多开发者的首选。尽管.NET Framework已演进至.NET 5 及更高版本,WinForms 仍作为核心组件保留,支持现有代码库的同时引入新特性。开发者可将项目迁移至.NET Core,享受性能提升和跨平台能力。迁移时需注意API变更,确保应用平稳过渡。通过自定义样式或第三方控件库,还可增强视觉效果。结合.NET新功能,WinForms 应用不仅能延续既有投资,还能焕发新生。 示例代码展示了如何在.NET Core中创建包含按钮和标签的基本窗口,实现简单的用户交互。
77 0
|
4月前
|
关系型数据库 Linux 数据库
linux设置信号量系统参数
linux设置信号量系统参数
|
6月前
|
Linux 网络安全 开发工具
Linux 管理远程会话 screen:掌握终端的多任务操作
`Linux screen` 命令让多任务管理变得更简单,尤其在SSH连接远程服务器时。创建新会话如`screen -S backup`,查看会话`screen -ls`,退出`exit`。高级功能包括直接在会话中运行命令,如`screen vim memo.txt`,会话共享以协同工作,以及通过`screen -r`或`-D -r`重新连接或强制恢复断开的会话。提高效率,确保任务不间断运行。
106 1
|
6月前
|
安全 Linux 数据处理
深入探究Linux的pathchk命令
`pathchk`是Linux命令,用于检查文件名和路径的可移植性,遵循POSIX规范。它检测不可移植字符,确保文件在不同系统间的兼容性。选项如 `-p`, `-P` 和 `--portability` 提供不同级别的检查。基本用法是 `pathchk [选项] [文件名/路径名] [后缀]`。例如,`pathchk /etc/httpd/conf/httpd.conf` 检查路径的可移植性。使用时要注意目标系统的特性,谨慎处理警告,并结合其他命令如`find`使用。在操作前备份数据以防止损失。
|
5月前
|
Linux
【Linux】生产者消费者模型——环形队列RingQueue(信号量)
【Linux】生产者消费者模型——环形队列RingQueue(信号量)
54 0
|
5月前
|
消息中间件 Linux
【Linux】进程间通信——system V(共享内存 | 消息队列 | 信号量)(下)
【Linux】进程间通信——system V(共享内存 | 消息队列 | 信号量)(下)
77 0