如果多个线程执行以下操作:
if ( !is_dir($dir) )
mkdir($dir, 0, true);
如果两个线程“同时”检测到该目录不存在,然后他们都尝试创建它,会发生什么?
是否mkdir
同步以防止发生坏事,或者有没有办法flock
确保只有一个线程创建目录和/或文件?
如果多个线程执行以下操作:
if ( !is_dir($dir) )
mkdir($dir, 0, true);
如果两个线程“同时”检测到该目录不存在,然后他们都尝试创建它,会发生什么?
是否mkdir
同步以防止发生坏事,或者有没有办法flock
确保只有一个线程创建目录和/或文件?
我知道这是一个老问题,但这样的事情非常有效,假设您有一个将错误转换为异常的错误处理程序(无论如何这是一个好主意):
/**
* 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);
}
});
只有其中一个会设法创建目录,另一个mkdir
会返回false
并发出警告
您也可以查看 php 中的这个错误,它与您的问题不完全一样,但它是相关的