Tcl mkdir的原子性

Tcl mkdir的原子性,tcl,nfs,mkdir,Tcl,Nfs,Mkdir,我在一个NFS v3文件系统上遇到了一个奇怪的问题(我觉得这很重要),它并行运行两个进程(根据下面的评论和我自己在这方面的知识,我认为语言不重要,我认为这足够可读): 对于那些不熟悉的人来说,tcl中的文件mkdir的行为与mkdir-p非常相似-只有当目录存在且不是目录时,它才会失败。我几乎100%(从来没有100%)认为在任何进程中都没有创建该文件,只有文件mkdir。问题并不总是发生,但在进行回归时,我们可能会遇到以下问题: Error: can't create directory "$

我在一个NFS v3文件系统上遇到了一个奇怪的问题(我觉得这很重要),它并行运行两个进程(根据下面的评论和我自己在这方面的知识,我认为语言不重要,我认为这足够可读):

对于那些不熟悉的人来说,tcl中的
文件mkdir
的行为与
mkdir-p
非常相似-只有当目录存在且不是目录时,它才会失败。我几乎100%(从来没有100%)认为在任何进程中都没有创建该文件,只有
文件mkdir
。问题并不总是发生,但在进行回归时,我们可能会遇到以下问题:

Error: can't create directory "$dir": file already exists
只有在
文件mkdir
处理过程中,
$dir
是现有的非目录文件时,才会发生这种情况。两个问题,第一个对我来说更重要:

  • mkdir不是原子的吗?特别是文件系统中的文件节点在创建过程中是否可以作为非目录存在任意时间
  • 假设这真的是一个错误,有没有一个简单的原子方法来做到这一点?我曾考虑过exec mkdir-p,但如果我是对的,这也会遇到同样的问题
  • 这已经很难重现,所以我宁愿在尝试修复之前尽可能确定。我来到这里是因为有一条消息说,
    nfs
    FS可能是问题所在,但我需要更多的专家建议。我不在乎两人是否都成功,我只是不希望他们(第一次尝试)失败

    最后一个音符

    过了很长一段时间,我又回到这一点上,这确实是一个tcl问题,但不仅仅是在nfs上,尽管nfs似乎让事情变得更糟了

    仍在寻找解释我为什么看到我看到的东西的答案-请参阅答案。

    将此作为错误打开

    错误已经修复


    tcl核心的人都很快

    在我发布错误一天后,TCL core的男男女女已经修复了这个问题

    固定在

    A谢谢卡尔文先生的建议


    旧的测试尝试:

    过了很长一段时间,我又回到这个问题上来,做了以下测试(在
    ext4
    ):

    两个带有
    tclsh
    的端子:

    1: while {1} {file mkdir bla}
    2: while {1} {file mkdir bla; file delete bla}
    
    1: while {1} {exec mkdir -p bla}
    2: while {1} {exec mkdir -p bla; file delete bla}
    
    1: while [ 1 ]; do mkdir -p bla; done
    2: while {1} {file mkdir bla; file delete bla}
    
    最终在
    1:
    上出错:

    can't create directory "bla": no such file or directory
    
    mkdir: cannot create directory ‘bla’: File exists
    
    两个带有
    tclsh
    的端子:

    1: while {1} {file mkdir bla}
    2: while {1} {file mkdir bla; file delete bla}
    
    1: while {1} {exec mkdir -p bla}
    2: while {1} {exec mkdir -p bla; file delete bla}
    
    1: while [ 1 ]; do mkdir -p bla; done
    2: while {1} {file mkdir bla; file delete bla}
    
    无错误。

    一个终端Bash-One
    tclsh

    1: while {1} {file mkdir bla}
    2: while {1} {file mkdir bla; file delete bla}
    
    1: while {1} {exec mkdir -p bla}
    2: while {1} {exec mkdir -p bla; file delete bla}
    
    1: while [ 1 ]; do mkdir -p bla; done
    2: while {1} {file mkdir bla; file delete bla}
    
    最后我上了
    1:

    can't create directory "bla": no such file or directory
    
    mkdir: cannot create directory ‘bla’: File exists
    
    但奇怪的是

    1: while [ 1 ]; do mkdir -p bla; rm -rf bla; done
    2: while {1} {file mkdir bla}
    
    can't create directory "bla": file already exists
    
    无错误(删除是罪魁祸首?)

    出错的可能性要小得多(所以删除是否也一样糟糕?)。当然,两个
    bash
    shell并不冲突:

    1: while [ 1 ]; do mkdir -p bla; rm -rf bla; done
    2: while [ 1 ]; do mkdir -p bla; done
    
    在NFS上,但不在EXT4上

    1: while {1} {file mkdir bla; exec rm -rf bla}
    2: while {1} {file mkdir bla}
    
    与一起失败

    1: while [ 1 ]; do mkdir -p bla; rm -rf bla; done
    2: while {1} {file mkdir bla}
    
    can't create directory "bla": file already exists
    
    在两个
    1:
    2:
    (随机)上

    结论

    file mkdir
    并不像我想象的那样是一个“薄”层,它可以产生竞态条件,其中一个
    mkdir
    认为正在生成的目录是一个文件<代码>文件删除也可能存在此问题或类似问题。在我的测试中,它可能也会导致失败,但在我最初的问题中,情况并非如此——对于NFS系统来说,情况更糟了,因为只有
    file mkdir
    很容易再现错误


    解决方案是使用
    exec mkdir-p
    。到目前为止,这对我们来说是全面有效的。

    FWIW,
    file mkdir
    的核心确实应该是
    mkdir()
    系统调用(或Windows上的
    CreateDirectory()
    )周围的一层薄薄的一层。我也这么想,并考虑删除tcl标记。你的评论解决了问题,谢谢。我认为这是值得申请的。