This文章指出,
fd = os.open('foo.lock', os.O_CREAT|os.O_EXCL|os.O_RDWR)
“在大多数文件系统上都是原子的”。这是真的(在Unix和Windows上)?在哪些文件系统上?
提到标志的docs状态在Unix和Windows上可用,因此它看起来像一个诱人的,跨平台的文件锁定方法(标志O_CREAT
和O_EXCL
确保调用进程创建文件。)
答案 0 :(得分:5)
对于符合UN * X标准(根据OpenGroup认证的POSIX / IEEE 1003.1)系统,保证了行为,因为open(2)
授权的OpenGroups规范。引用:
O_EXCL
如果设置了O_CREAT和O_EXCL,则如果文件存在,open()将失败。检查文件是否存在以及文件的创建(如果不存在)应该是原子,相对于执行open()的其他线程,使用O_EXCL和O_CREAT在同一目录中命名相同的文件名组。如果设置了O_EXCL和O_CREAT,并且路径名称为符号链接,则open()将失败并将errno设置为[EEXIST],而不管符号链接的内容如何。如果设置了O_EXCL且未设置O_CREAT,则结果未定义。
“常见”UN * X和UN * X系统(Linux,MacOSX,* BSD,Solaris,AIX,HP / UX)肯定会表现得那样。
由于Windows API没有open()
,因此必须根据本机API重新实现库函数,但可以维护语义。
我不知道哪些广泛使用的系统不符合; QNX虽然没有经过POSIX认证,但在open()
的文档中也有相同的声明。 * BSD联机帮助页未明确提及“原子性”,但Free / Net / OpenBSD实现了它。甚至像SymbianOS这样的外来物(像Windows一样没有UN * X-ish open
系统调用)也可以进行原子打开/创建。
要获得更有趣的结果,请尝试查找一个操作系统/ C运行时库,该库具有open()
但不为其实现上述语义...以及Python将在哪个用线程运行(让你到那里,MSDOS ......)。
编辑:我的帖子特别关注“哪些操作系统具有open
的这种特性?” - 答案是“几乎所有人”。 WRT。但是,对于文件系统,图片是不同的,因为网络文件系统 - 无论是NFS,SMB / CIFS还是其他人,都不会始终保持O_EXCL
,因为这可能会导致拒绝服务(如果客户端执行open(..., O_EXCL, ...)
然后只是停止与文件服务器通话/关闭,其他所有人都将被锁定)。