我对mkstemp()函数的工作过程感到困惑。
在man函数的mkstemp页面中,据说该函数生成唯一的名称并创建一个具有该名称的文件。
我认为,当mkstemp()在目录中检查该文件名并在实际创建该文件之前发现它是唯一的时,另一个程序可以使用完全相同的名称创建该文件(虽然可能性很低,但理论上是可能的)。尽管这样,当它使用O_EXCL标志时,它将无法创建文件。因此,它必须再次检查一个新的文件名并创建它。这是mkstemp()工作的实际过程吗?
因此,我认为检查文件名和创建文件实际上都不是原子地处理它。(我可能错了)
使用**POSIX** system
发布于 2022-01-16 12:43:06
mkstemp()究竟是如何工作的?
源代码是算法的字面描述。接受一个实现并检查它。
https://github.com/lattera/glibc/blob/master/misc/mkstemp.c -> https://github.com/lattera/glibc/blob/master/sysdeps/posix/tempname.c
O_CREAT | O_EXCL XXXXXX,如果返回未知错误,如果存在该文件,则repeat所以没有“检查”,文件从一开始就用O_CREAT | O_EXCL打开,所以创建和检查是一起完成的。有关https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html标志的说明,请参阅open。
发布于 2022-01-17 06:25:55
(虽然机会很低,但理论上是可能的)
不,这是不可能的(甚至理论上),因为open()系统调用mkstemp()用来创建文件,保证没有任何两个进程可以同时使用O_CREAT和O_EXCL创建相同的文件。当内核创建文件时,inode目录被锁定(因此,不允许同时在该目录中创建任何其他文件),这保证了两个open()的序列化(一个先序列化,另一个序列化,但不是同时序列化)--这意味着当第二个进程有机会创建文件时,open()调用失败,因为文件已经由另一个进程创建了。为了最小化这种情况,函数通常使用进程的pid作为名称的一部分,因此两个进程同时不能生成相同的文件名,因为它们具有不同的进程ids) mkstemp()会用可能不同的名称重试系统调用,或者只是失败。
https://stackoverflow.com/questions/70729711
复制相似问题