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

 

posted @ 2014-09-14 14:01  23lalala  阅读(410)  评论(0编辑  收藏  举报