从多个线程创建目录

时间:2013-03-12 08:14:43

标签: php

如果多个线程执行以下操作:

if ( !is_dir($dir) )
    mkdir($dir, 0, true);

如果两个线程“同时”检测到该目录不存在然后它们都尝试创建它会发生什么?

mkdir是否已同步以防止发生不良事件,或者有flock方式确保只有一个线程创建目录和/或文件?

2 个答案:

答案 0 :(得分:1)

其中只有一个会设法创建目录,另一个mkdir会返回false并发出警告

您还可以在php中查看此bug,与您的问题不一样,但它是相关的

答案 1 :(得分:1)

我知道这是一个古老的问题但是这样的事情非常有效,假设你有一个错误处理程序将错误转换为异常(无论如何这都是个好主意):

    /**
     * Create a folder in a thread safe way
     * Between 'is_dir' and 'mkdir' another thread could have created a folder. 
     * This can cause the system to raise an unwarrented error
     * 
     * Returns TRUE if folder was created, NULL if folder already exists
     * 
     * Throws exception on any other error
     *
     * @param  array   $array
     * @param  string  $key
     * @param  mixed   $value
     * @return array
     */
    function mkdir_thread_safe($dir, $permissions = 0777, $recursive = false)
    {   
        if(is_dir($dir)) return;

        try {
             mkdir($dir, $permissions, $recursive);
        }
        catch (\ErrorException $e){

            if(is_dir($dir)) return;

            throw $e;
        }

        return true;
    }

这是异常转换处理程序的错误 - 无论如何这都是很好的做法,应该在任何应用程序入口点的开头添加。一些现代框架(如laravel)默认处理此问题,因此如果您使用laravel,则您的错误将已转换为异常。

set_error_handler(function ($level, $message, $file, $line, $context)
{
    if (error_reporting() & $level)
    {
        throw new ErrorException($message, $level, 0, $file, $line);
    }
});