【问题标题】:Why doing I/O in Linux is uninterruptible?为什么在 Linux 中进行 I/O 是不间断的?
【发布时间】:2018-02-12 22:04:24
【问题描述】:

这背后的原理是什么?如果允许执行 I/O 的进程处理信号会产生什么不良后果?

【问题讨论】:

    标签: linux process io linux-kernel sleep


    【解决方案1】:

    既然我已经阅读了 Maurice Bach 的《Unix 操作系统的设计》一书,让我自己来回答这个问题。

    简而言之,让 I/O 不可中断是为了让 I/O 任务尽快完成,不受信号干扰。

    我从书中获得的一些相关知识:

    1. “不间断”一词应指“不间断睡眠”。当进程处于不间断睡眠时,它不能被信号唤醒,也不会处理信号。
    2. 进程在以下情况下处理信号:它正在内核模式下运行,即将返回用户模式。湾。当睡眠可中断时,它即将进入和离开睡眠状态。
    3. 当睡眠进程被信号唤醒时会发生什么?它将处理信号,默认操作是退出进程。当进程等待 I/O 完成时,您当然不希望它过早退出。

    【讨论】:

    • 很好的答案。唯一的问题是这并不能回答他问题的后果部分。过早退出会有什么后果?
    【解决方案2】:

    根据Linux Developers Documentation,是为了防止数据丢失,避免硬件进入不一致状态。

    想象一下如果read()(例如来自磁盘)是可中断的并且信号处理程序(除其他职责外)更改了读取缓冲区会发生什么。由于信号是异步的,读取结果将无法重现。如果写作被打断,也会出现类似的混乱。

    【讨论】:

    • 但是read(2) 是可中断的kernel.org/doc/man-pages/online/pages/man2/read.2.html(然后你得到errno==EINTR);但是,当文件系统操作正在进行时,进程会保持D 状态。
    • 即使在信号中断 read() 调用后进程仍处于活动状态,也会丢失数据,因为此读取必须已成功启动从磁盘(hw)到内核的数据传输,但不是从内核到用户进程(read() 返回 EINTR)。
    • 答案不清楚。为什么会出现“读取结果无法重现”的问题?显然,我们不希望在向进程发送异步信号后得到定义明确、可重现的结果。
    • 哈哈玩得很好@Wallyk....打算将您的链接作为参考添加到我的作业中
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    • 2015-01-17
    • 2017-05-19
    相关资源
    最近更新 更多