编写多线程应用程序时,遇到的最常见问题之一是竞争条件.
我对社区的问题是:
什么是比赛条件?你怎么发现它们?你怎么处理它们?最后,你如何防止它们发生?
让我们考虑一个示例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);
Run Code Online (Sandbox Code Playgroud)
我想知道某个用户当前是否正在执行此脚本并且文件"foo.txt"被锁定,同时或在其执行完成之前,如果其他用户调用此脚本,那么会发生什么?第二个用户是否会等待第一个用户解锁文件?或第二个用户输入的行删除将失败?
我有一个新手(隔壁的少年)写了一些PHP代码来跟踪我的网站上的一些用法.我不熟悉php,所以我要问一些关于并发文件访问的问题.
我的原生应用程序(在Windows上)偶尔通过点击包含我的PHP脚本的URL将一些数据记录到我的网站.本机应用程序不检查返回的数据.
$fh = fopen($updateFile, 'a') or die("can't open file");
fwrite($fh, $ip);
fwrite($fh, ', ');
fwrite($fh, $date);
fwrite($fh, ', ');
fwrite($fh, implode(', ', $_GET));
fwrite($fh, "\r\n");
fclose($fh);
Run Code Online (Sandbox Code Playgroud)
这是一个流量较低的站点,数据并不重要.但是如果两个用户发生冲突并且脚本的两个实例都试图在文件中添加一行,会发生什么?在php中是否有任何隐式文件锁定?
上面的代码至少是安全的,不会锁定并且永远不会将控制权返回给我的用户吗?该文件可以被破坏吗?如果我上面的脚本每月删除文件,如果脚本的另一个实例正在写入文件,会发生什么?
我正在尝试模拟繁忙站点上的文件写入.我写了下面的代码,最终冻结了计算机.
$loop = 10000;
$sleep = 500000;
$i =0;
while($i < $loop) {
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$starttime = $mtime;
$handler = fopen($file,"a+");
if($handler) {
if (flock($handler, LOCK_EX)) {
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$endtime = $mtime;
$totaltime = ($endtime - $starttime);
fwrite($handler,"Script 1 took $totaltime secs\n");
}
flock($handler, LOCK_UN);
fclose($handler);
}
$i++;
usleep($sleep);
}
Run Code Online (Sandbox Code Playgroud)
我无法使用LOCK_NB,因为它无法在Windows上运行.如果少于13个进程同时执行上述代码,则代码可以正常工作.我如何应对这种僵局?