【问题标题】:PHP fopen (x flag) guaranteed to run only once?PHP fopen(x标志)保证只运行一次?
【发布时间】:2013-03-09 03:25:02
【问题描述】:

PHP 允许我们在执行fopen 时使用x 标志:

创建和打开仅供写作;将文件指针放在 文件的开头。

如果文件已经存在,则 fopen() 调用 将通过返回 FALSE 并生成 level 错误而失败 E_WARNING。

如果文件不存在,请尝试创建它。这是 相当于为底层指定 O_EXCL|O_CREAT 标志 open(2) 系统调用。

这是否意味着无论我们有多少并发 fopen 请求(来自不同用户),保证文件只会被创建一次并且永远不会被覆盖?

if ($handle = fopen("part006", "x+b")) {
    do_some_processing();
    echo "You managed to process.";
    /*

    can we guarantee that only 1 user (http request)
    will ever process the function and see the
    message "you managed to process" ?

    */
} else {
    echo "You failed to process.";
}

【问题讨论】:

    标签: php web-applications locking mutex fopen


    【解决方案1】:

    Answer:只要其他进程也使用O_EXCL,保证文件只会被创建一次,永远不会被覆盖。如果他们不这样做,则可以覆盖该文件。因此,使用 O_EXCL 打开(创建)一个文件并不意味着该文件有点写保护

    解释:fopen 使用底层的open 系统调用。来自手册页:man 2 open

    O_EXCL

    如果设置了 O_CREAT 和 O_EXCL,如果文件存在,则 open() 将失败。检查文件是否存在以及如果文件不存在则创建文件对于执行 open() 的其他线程在同一目录中命名相同的文件名并设置了 O_EXCL 和 O_CREAT 应该是原子的。如果设置了 O_EXCL 和 O_CREAT,并且路径名称为符号链接,则 open() 将失败并将 errno 设置为 [EEXIST],而不管符号链接的内容如何。如果设置了 O_EXCL 而未设置 O_CREAT,则结果未定义。

    【讨论】:

    • windows也保证独占性吗?
    • 我不确定(但很可能).. 将尝试找到该信息..(不幸的是 man 在 Windows 上不起作用;))
    • @Pacerier 阅读一些邮件列表,这似乎不适用于 Windows。但我不确定,因为我目前没有用于测试的窗口。你能测试吗?如果它不起作用,那么您应该为此目的使用flock()。不一样,但它可能对您有所帮助(不知道您的应用程序需要)。请注意我对 question 的回答,这是与 flock() 相关的,可能会有所帮助
    • 我在 windows 上也没有 php 进行测试。只是在考虑便携性。
    • 稍后将对其进行测试并发表评论。 flock() 可以在 Windows 上运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-24
    • 2012-01-08
    • 2014-12-07
    • 1970-01-01
    • 2013-07-28
    • 2015-04-10
    相关资源
    最近更新 更多