解释Linux *** 作系统中的不可中断睡眠态的存在理由?

解释Linux *** 作系统中的不可中断睡眠态的存在理由?,第1张

不可中断睡眠也就是D状态。比如内核态进程在等待某项资源,这时候是不允许被打断的,否则可能导致系统进入未知状态,或者引发严重的系统异常,所以对于这种 *** 作,定义D状态进行保护。使其在完成本次 *** 作之前,不可以被任何异步状态打断。

2.schedule()在切换进程时,保存当前的进程上下文(CPU寄存器的值、进程的状态以及堆栈中的内容),以便以后恢复此进程运行。中断发生后,内核会先保存当前被中断的进程上下文(在调用中断处理程序后恢复);但在中断处理程序里,CPU寄存器的值肯定已经变化了吧(最重要的程序计数器PC、堆栈SP等),如果此时因为睡眠或阻塞 *** 作调用了schedule(),则保存的进程上下文就不是当前的进程context了.所以不可以在中断处理程序中调用schedule()。3.2.4内核中schedule()函数本身在进来的时候判断是否处于中断上下文:if(unlikely(in_interrupt()))BUG()因此,强行调用schedule()的结果就是内核BUG,但我看2.6.18的内核schedule()的实现却没有这句,改掉了.4.中断handler会使用被中断的进程内核堆栈,但不会对它有任何影响,因为handler使用完后会完全清除它使用的那部分堆栈,恢复被中断前的原貌.5.处于中断context时候,内核是不可抢占的,因此,如果休眠,则内核一定挂起.----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------先把中断处理流程给出来1.进入中断处理程序---2.保存关键上下文----3.开中断(sti指令)---4.进入中断处理程序的 handler---5.关中断(cli指令)----6.写EOI寄存器(表示中断处理完成)----7.开中断。复制代码硬中断:对应于上图的1、2、3步骤,在这几个步骤中,所有中断是被屏蔽的,如果在这个时候睡眠了, *** 作系统不会收到任何中断(包括时钟中断),系统就基本处于瘫痪状态(例如调度器依赖的时钟节拍没有等等)软中断:对应上图的4(当然,准确的说应该是4步骤的后面一点,先把话说保险点,免得思一克又开始较真)。这个时候不能睡眠的关键是因为上下文。大家知道 *** 作系统以进程调度为单位,进程的运行在进程的上下文中,以进程描述符作为管理的数据结构。进程可以睡眠的原因是 *** 作系统可以切换不同进程的上下文,进行调度 *** 作,这些 *** 作都以进程描述符为支持。中断运行在中断上下文,没有一个所谓的中断描述符来描述它,它不是 *** 作系统调度的单位。一旦在中断上下文中睡眠,首先无法切换上下文(因为没有中断描述符,当前上下文的状态得不到保存),其次,没有人来唤醒它,因为它不是 *** 作系统的调度单位。此外,中断的发生是非常非常频繁的,在一个中断睡眠期间,其它中断发生并睡眠了,那很容易就造成中断栈溢出导致系统崩溃。如 果上述条件满足了(也就是有中断描述符,并成为调度器的调度单位,栈也不溢出了,理论上是可以做到中断睡眠的),中断是可以睡眠的,但会引起很多问题.例 如,你在时钟中断中睡眠了,那 *** 作系统的时钟就乱了,调度器也了失去依据;例如,你在一个IPI(处理器间中断)中,其它CPU都在死循环等你答复,你确 睡眠了,那其它处理器也不工作了;例如,你在一个DMA中断中睡眠了,上面的进程还在同步的等待I/O的完成,性能就大大降低了还可以举出很多例子。 所以,中断是一种紧急事务,需要 *** 作系统立即处理,不是不能做到睡眠,是它没有理由睡眠。中断产生是随机的,假设某次中断一个内核线程,而且按照你说的方案,这个线程的task结构就会被借用,线程就会去睡眠。被打断线程的优先级如果太低,那 么它很难有机会再执行,某些情况下可能造成系统hang。如果临时提高被打断线程的优先级,那么又需要设计新的唤醒机制来保证阻塞同一锁上的高优先级的线 程被先唤醒。同时,要实现临时提高被打断线程的优先级,又需要再锁的获取流程增加改变优先级的算法。

hd-idle无论怎样设置都无法使用硬盘在空闲时休眠,实在找不到原因。在查找相关资料时发现在linux *** 作系统还有个叫hdparm的硬盘控制软件,然后在OPENWRT软件搜索果真有这个软件,然后就安装试试。不想真能让我的硬盘在设置好的空闲时间后进入省电模式也可以说是休眠模式吧!给出我的安装使用过程。注:我的路由(HG255D刷OPENWRT)装有迅雷固件、个人博客、aria2、百度同步+常用共享组件!使用还是可以的负载不算很高。之前有人说装迅雷固件后不能休眠,但我的可以休眠。不能休眠的可以试试这个软件...

OPENWRT路由上安装与设置:

一、安装hdparm

opkg update

opkg install hdparm

二、执行命令:

hdparm -S 60 /dev/sda (放到开机启动项就可以每次开机都生效!)

hdparm -y /dev/sda (这个命令是立即休眠,测试硬盘是否休眠成功。)

说明:hdparm -S 60 /dev/sda 设置超时值(5分钟)使硬盘进入休眠模式(省电模式)(这个 S数值/12=分钟); /dev/sda 为挂载的硬盘路径,ls /dev/sda*查看你的盘符。

三、执行完hdparm -S 60 /dev/sda 这个命令时你的路由已经设置为5分钟休眠了。(注:5分钟硬盘无 *** 作时省电模式,休眠时接到读写命令会自动唤醒进入工作模式)**Linux hdparm 命令**

四、hdparm功能说明:显示与设定硬盘的参数。

语法:hdparm -CfghiIqtTvyYZ-A <0或1>-d <0或1>-K <0或1>-n <0或1>-P -S -W <0或1>[设备]

补充说明:hdparm可检测,显示与设定IDE或SCSI硬盘的参数。

测试各硬盘读取速度判断硬盘故障

在服务端命令窗口中执行如下命令

hdparm -t /dev/hda (IDE硬盘)

hdparm -t /dev/sda (SATA、SCSI、硬RAID卡阵列)

hdparm -t /dev/md0 (软RAID设备)

测试结果在空载情况下应 >40M/s ,在负载情况下平均应 >20M/s 为正常,如测试结果极低则需要进一步使用硬盘专用检测工具测试是否为硬盘故障。

参数:

-a 设定读取文件时,预先存入块区的分区数,若不加上选项,则显示目前的设定。

-A<0或1>启动或关闭读取文件时的快取功能。

-c 设定IDE32位I/O模式。

-C 检测IDE硬盘的电源管理模式。

-d<0或1>设定磁盘的DMA模式。

-f 将内存缓冲区的数据写入硬盘,并清楚缓冲区。

-g 显示硬盘的磁轨,磁头,磁区等参数。

-h 显示帮助。

-i 显示硬盘的硬件规格信息,这些信息是在开机时由硬盘本身所提供。

-I 直接读取硬盘所提供的硬件规格信息。

-k<0或1>重设硬盘时,保留-dmu参数的设定。

-K<0或1>重设硬盘时,保留-APSWXZ参数的设定。

-m 设定硬盘多重分区存取的分区数。

-n<0或1>忽略硬盘写入时所发生的错误。

-p 设定硬盘的PIO模式。

-P 设定硬盘内部快取的分区数。

-q 在执行后续的参数时,不在屏幕上显示任何信息。

-r<0或1>设定硬盘的读写模式。

-S 设定硬盘进入省电模式前的等待时间。

-t 评估硬盘的读取效率。

-T 平谷硬盘快取的读取效率。

-u<0或1>在硬盘存取时,允许其他中断要求同时执行。

-v 显示硬盘的相关设定。

-W<0或1>设定硬盘的写入快取。

-X 设定硬盘的传输模式。

-y 使IDE硬盘进入省电模式。

-Y 使IDE硬盘进入睡眠模式。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/9011621.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-23
下一篇 2023-04-23

发表评论

登录后才能评论

评论列表(0条)

保存