Herd prevention

I am trying to simulate a file entry on a busy site. I wrote the following code, which ultimately ends up freezing the computer.

$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);
}

I cannot use LOCK_NB because it will not work on Windows. The code works fine if less than 13 processes execute the above code. How can I deal with this situation at an impasse?

+5
source share
4 answers

Reading your code, I think you need to move "flock ($ handler, LOCK_UN)"; inside the "if (flock ($ handler, LOCK_EX)) {}" conditional block.

, , datestamped ( , ) , flock(), fopen(), fwrite(), fclose() script .

+ , script . , , script (s) "" .

+2

Hy

file_put_contents():

<?php

$file = 'file.txt';

$str = "some text\n";

file_put_contents($file, $str, FILE_APPEND | LOCK_EX);

?>

+1

php-, AB (apache benchmark), apache EX >

ab -n 1000 -c 200 http://localhost/your.php

200 1000 .

+1

"" LOCK_EX mkdir(), : fooobar.com/questions/473925/...

Example:

<?php
$file = 'deadlock.txt';
$loop = 10000;
$sleep = 500000;
$i = 0;
while ($i < $loop) {
    $starttime = microtime(true);
    $handler = fopen($file, 'a+');
    if ($handler) {
        if (!file_exists($file . '_lock')) {
            if (mkdir($file . '_lock')) {
                if (flock($handler, LOCK_EX)) {
                    $endtime = microtime(true);
                    $totaltime = ($endtime - $starttime);
                    $totaltime = number_format($endtime - $starttime, 10);
                    if ($totaltime > 1) {
                        break;
                    }
                }
                flock($handler, LOCK_UN);
                fclose($handler);
                rmdir($file . '_lock');
            }
        }
    }
    $i++;
    usleep($sleep);
}
?>

As you can see, I added break;to avoid a dead end. If the scripts stop, you can view the log file.

On Linux, I use this trick mkdir()without flock(), since it is atomic. I do not know if this works on Windows.

0
source

All Articles