gpt4 book ai didi

c - 如果进程终止但系统继续运行, WriteFile() 会是原子的吗?

转载 作者:可可西里 更新时间:2023-11-01 10:05:57 27 4
gpt4 key购买 nike

如果我的进程在随机时刻终止但操作系统继续正常运行,Windows 会保证对 WriteFile 的个别调用吗?是原子的(又名全有或全无)?
或者我可以获得部分/撕裂的写入?


注意:我特意不征求有关如何练习防御性编码的建议。

这是一个严格关于 Microsoft Windows 操作系统本身行为的问题。

要 100% 完美地一目了然我们可以并且明确地确实相信用户代码的行为是正常的。没有没有未定义的行为 或任何类似的行为。假定所有进程终止都是通过明确定义的行为发生的,例如未处理的异常或调用TerminateProcess不是内存损坏等。

另外,请特别注意这里不需要担心 C++ 析构函数;这是 C。

我希望所有关于用户代码的次要问题都可以解决。

最佳答案

WriteFile 在您的进程在执行时被终止的情况下肯定不是原子的,如果您的进程没有被杀死,它甚至不是原子的。

此外,“全部写入或不写入” 甚至不是原子写入的正确定义。所有的都可以被写入,但与来自另一个进程的独立写入混合在一起。如果保证写入是原子的,则必须保证(读作:锁定)这不会发生。

除了实现适当的原子性会带来相当大的额外麻烦,而且对于普通日常用户而言几乎没有任何好处,您还可以猜测 WriteFile 不是原子性的:

  1. API 文档中未提及。您可以打赌,这会被突出地提及,因为它是一个非常重要的、与众不同的功能。
  2. 存在 lpNumberOfBytesWritten 参数。写入可能仍会失败(例如磁盘已满),但如果该函数保证是原子的,您就会知道它是成功还是失败,并且您已经知道要写入多少字节,因此不需要返回该数字。
  3. 存在TxF .尽管 TxF 所做的不仅仅是使单个写入原子化,但有理由假设微软不会浪费大量时间和金钱来实现这样一个野兽,因为“正常”文件系统操作已经或多或少地工作了。<
  4. 据我所知,没有其他主流操作系统提供这样的保证。 Linux 确实对 writev(但对 write)提供了某种原子性保证,因为您的写入不会与来自其他进程的写入混合.但这与在进程终止时保证原子性完全不同。

但是,在使用 FILE_FLAG_NO_BUFFERING 打开的句柄上的重叠写入在技术上在进程终止方面是原子的(但不是在故障方面,例如磁盘已满或任何其他方面!)。诚然,这样说在实现细节上有点诡辩,并不是操作系统给出的实际保证,但从某种角度来说,这样说肯定是正确的。
无法终止正在执行无缓冲、重叠 I/O 操作的进程。那是因为操作系统正在执行 DMA 传输到该进程的地址空间。这当然意味着进程不能终止,因为操作系统会回收物理页面。因此,当此类 I/O 操作正在运行时,操作系统将拒绝终止进程。
您可以通过发出几个大的无缓冲重叠请求(几 GB)来验证这一点,并尝试在任务管理器中终止您的进程。它只会在 I/O 完成时被杀死(因此,几秒钟后)。当您第一次看到它发生并且没想到会发生时,这会是一个很大的惊喜!

关于c - 如果进程终止但系统继续运行, WriteFile() 会是原子的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25028260/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com