php多进程写入文件

测试一

$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

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。