如果进程终止但系统继续运行,WriteFile()将是原子的吗? [英] Will WriteFile() be atomic if the process is terminated but the system continues running?

查看:70
本文介绍了如果进程终止但系统继续运行,WriteFile()将是原子的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我的进程在任意时刻终止,但是操作系统继续正常运行,Windows将保证对还是可以得到部分/撕裂的写入?

If my process is terminated at a random moment but the operating system continues to run properly, will Windows guarantee that individual calls to WriteFile are atomic (a.k.a. all-or-nothing)?
Or can I get partial/torn writes?

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

This is strictly a question about the behavior of the Microsoft Windows operating system itself.

要做到100%完美的透明我们可以明确地做到相信用户代码具有合理的行为.没有 没有未定义的行为 或类似的任何内容.假定所有进程终止都是通过明确定义的行为发生的,例如未处理的异常或对 TerminateProcess 的调用,内存损坏等.

To be 100% perfectly crystal clear, we can and explicitly do trust the user code to behave sanely. There is no undefined behavior or anything of the sort. All process terminations are assumed to occur through a well-defined behavior such as unhandled exceptions or calls to TerminateProcess, not memory corruption, etc.

还要特别注意,这里没有C ++析构函数值得担心.这是C.

Also, specifically note that there are no C++ destructors to worry about here; this is C.

我希望可以消除所有与用户代码有关的次要问题.

I hope that puts all the secondary concerns about the user code to rest.

推荐答案

WriteFile 当然是不是原子的如果您的进程没有被杀死,那甚至不是原子的.

WriteFile is certainly not atomic in the case of your process being terminated while it is executing, it is not even atomic if your process is not being killed.

此外,全部或全部未写入" 甚至不是原子写入的正确定义.可以全部写入,但是与来自另一个进程的独立写入混合在一起.如果写保证是原子的,则必须保证不会发生这种情况.

Also, "all or nothing written" is not even a proper definition of an atomic write. All could be written, but intermingled with an independent write from another process. If writes are guaranteed to be atomic, there must be a guarantee (read as: lock) that this doesn't happen.

除了实现适当的原子性会带来相当大的麻烦之外,对于普通用户而言,这几乎是没有好处的,您还可以猜测 WriteFile 不是来自以下方面的原子性:

Apart from the fact that implementing proper atomicity would be considerable extra trouble with very little to gain for the average everyday user, you can also guess that WriteFile is not atomic from:

  1. API文档中未提及.您可以打赌,这将被突出提及,因为它是一个非常大的,与众不同的功能.
  2. lpNumberOfBytesWritten 参数的存在.写操作仍可能失败(例如,磁盘已满),但是如果保证该函数是原子的,则您将知道它成功还是失败,并且您已经知道要写入多少字节,因此无需返回该数字.
  3. TxF的存在.尽管TxF所做的不仅是使单个写入成为原子操作,而且可以合理地假设Microsoft在正常"文件系统操作或多或少已经可以正常工作的情况下,在实现这种野兽上不会浪费大量的时间和金钱.li>
  4. 据我所知,没有其他主流操作系统能够提供这样的保证.Linux确实在 writev 上提供了原子性保证(但在 write 上没有),只要您的写入不会与其他进程的写入混合在一起.但这与在流程终止的情况下保证原子性完全不同.
  1. The absence of mention in the API documentation. You can bet that this would be prominently mentioned, as it is a really big, distinguishing feature.
  2. The presence of the lpNumberOfBytesWritten parameter. A write might still fail (e.g. disk full) but if the function was guaranteed to be atomic, you would know that it either succeeded or failed, and you already know how many bytes you were going to write, so returning that number is unnecessary.
  3. The presence of TxF. Although TxF does a lot more than just making single writes atomic, it is reasonable to assume that Microsoft wouldn't waste considerable time and money in implementing such a beast when "normal" filesystem operations already more or less work the like anyway.
  4. No other mainstream operation system that I know of gives such a guarantee. Linux does give a sort of atomicity guarantee on writev (but not on write) insofar as your writes will not be intermingled with writes from other processes. But that is not at all the same thing as guaranteeing atomicity in presence of process termination.

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

However, overlapped writes on a handle opened with FILE_FLAG_NO_BUFFERING are technically atomic in respect of process termination (but not in respect of failure, such as disk full or in any other respect!). Saying so is admittedly a bit of a sophistry on an implementation detail, not an actual guarantee given by the operating system, but from a certain point of view it's certainly correct to say so.
A process that is performing an unbuffered, overlapped I/O operation cannot be terminated. That is because the OS is doing DMA transfers into that process' address space. Which of course means that the process cannot be terminated since the OS would reclaim the physical pages. The OS will therefore refuse to terminate a process while such an I/O operation is running.
You can verify this by firing off a couple of big unbuffered overlapped requests (a few GB) and try killing your process in Task Manager. It will only be killed when the I/O is complete (so, after some seconds). That comes as a big surprise when you see it happen for the first time and don't expect it!

这篇关于如果进程终止但系统继续运行,WriteFile()将是原子的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆