测试一
$begin = time(); for ($i=0; $i<10000; $i++) { $fp = fopen("tmp", ‘r+‘); fseek($fp, 0, SEEK_END); fwrite($fp, str_repeat($argv[1],1024*32).PHP_EOL); fclose($fp); } $end = time(); echo "time use: ".($end-$begin).PHP_EOL;
php write.php b
php write.php a
wc -l tmp
10450 tmp
测试结果:
与预期的2W行不相符
错误分析:
seek定位到文件末尾的之后,可能因为其他进程已经写入文件,当前进程进行了覆盖
测试二
$begin = time(); for ($i=0; $i<10000; $i++) { $fp = fopen("tmp", ‘a+‘); fwrite($fp, str_repeat($argv[1],1024*32).PHP_EOL); fclose($fp); } $end = time(); echo "time use: ".($end-$begin).PHP_EOL;
php write.php b
php write.php a
wc -l tmp
20000 tmp
测试结果:
与预期的2W行相符,但是检查文件内容
检查脚本,检查一行是不是同时含有a和b
<?php $fp = fopen("tmp", ‘r+‘); while (!feof($fp)) { $line = fgets($fp, 1024*1024); if (strstr($line, ‘a‘) && strstr($line, ‘b‘)) { echo ‘not pass‘.PHP_EOL; for ($i=0;$i<strlen($line);$i++){ echo ord($line[$i]).PHP_EOL; } die; } } echo ‘pass‘.PHP_EOL;
php check.php >ts
ts内容
not pass 97 97 . . . 98 98 10
错误分析:
php的fwrite是带buffer的,写入一行的内容大于buffer的长度,进程A和进程B是轮流调用write到同一行,就导致了这种结果
测试三
顺序写
$begin = time(); $fp = fopen("tmp", ‘w+‘); for ($i=0; $i<200000; $i++) { fwrite($fp, str_repeat($argv[1],1024*32).PHP_EOL); } fclose($fp); $end = time(); echo "time use: ".($end-$begin).PHP_EOL;
php write.php a
time use: 13
$begin = time(); for ($i=0; $i<200000; $i++) { $fp = fopen("tmp", ‘a+‘); fwrite($fp, str_repeat($argv[1],1024*32).PHP_EOL); fclose($fp); } $end = time(); echo "time use: ".($end-$begin).PHP_EOL;
php write.php a
time use: 16
时间: 2024-09-30 15:12:41