当文件被一个进程锁定时,php错误行为 让我们考虑一个PHP脚本,它删除用户输入的行: $DELETE_LINE = $_GET['line']; $out = array(); $data = @file("foo.txt"); if($data) { foreach($data as $line) if(trim($line) != $DELETE_LINE) $out[] = $line; } $fp = fopen("foo.txt", "w+"); flock($fp, LOCK_EX); foreach($out as $line) fwrite($fp, $line); flock($fp, LOCK_UN); fclose($fp);
我想知道,如果某个用户当前正在执行此脚本,并且文件“foo.txt”在同一时间或在其执行完成之前被锁定,如果其他用户调用此脚本,那么会发生什么情况?当文件被一个进程锁定时,php错误行为 让我们考虑一个PHP脚本,它删除用户输入的行: $DELETE_LINE = $_GET['line']; $out = array(); $data = @file("foo.txt"); if($data) { foreach($data as $line) if(trim($line) != $DELETE_LINE) $out[] = $line; } $fp = fopen("foo.txt", "w+"); flock($fp, LOCK_EX); foreach($out as $line) fwrite($fp, $line); flock($fp, LOCK_UN); fclose($fp);,php,Php,我想知道,如果某个用户当前正在执行此脚本,并且文件“foo.txt”在同一时间或在其执行完成之前被锁定,如果其他用户调用此脚本,那么会发生什么情况? 第二个用户进程是否会等待第一个用户解锁文件?或者第二个用户输入的行删除将失败?如果在另一个进程锁定文件时尝试获取独占锁,则您的尝试将等待文件解锁。这就是锁定的全部要点 请参阅的Linux文档,其中描述了它在操作系统中的一般工作方式。PHP在幕后使用,因此通常支持NFS共享 没有超时。如果您想自己实现超时,可以执行以下操作: $count = 0;
第二个用户进程是否会等待第一个用户解锁文件?或者第二个用户输入的行删除将失败?如果在另一个进程锁定文件时尝试获取独占锁,则您的尝试将等待文件解锁。这就是锁定的全部要点 请参阅的Linux文档,其中描述了它在操作系统中的一般工作方式。PHP在幕后使用,因此通常支持NFS共享 没有超时。如果您想自己实现超时,可以执行以下操作:
$count = 0;
$timeout_secs = 10; //number of seconds of timeout
$got_lock = true;
while (!flock($fp, LOCK_EX | LOCK_NB, $wouldblock)) {
if ($wouldblock && $count++ < $timeout_secs) {
sleep(1);
} else {
$got_lock = false;
break;
}
}
if ($got_lock) {
// Do stuff with file
}
$count=0;
$timeout_secs=10//超时的秒数
$got_lock=true;
而(!flock($fp,LOCK_EX | LOCK_NB,$wouldblock)){
如果($wouldblock&&$count++<$timeout\u秒){
睡眠(1);
}否则{
$got_lock=false;
打破
}
}
如果($got_lock){
//处理文件
}
这意味着,在上一个进程解锁文件时,另一个进程将等待。我想知道另一个进程将等待文件解锁多长时间?有超时吗?没有超时。我添加了使用非阻塞选项实现超时的代码。请注意,根据PHP文档,Windows不支持LOCK\u NB
和$wouldblock
参数:如果您无法控制哪些服务器将运行您的软件,那么您也无法实际使用上述代码。在这种情况下,我觉得根本无法实现任何类型的“锁定超时”。请记住,在使用此技术时,请求锁定的不同进程不会处于严格的队列中。每次进程进入sleep()
阶段时,它都会跳出队列并在休眠后返回到队列的末尾。这对您的应用程序来说可能没问题,但这只是意味着无法保证每个进程必须等待多长时间以及它们将以何种顺序运行。应该注意的是,如果在等待锁定时超过最大脚本执行时间,则进程将终止。这是最明确的超时。