Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing deadlock caused by flock

Tags:

php

flock

I am trying to simulate a file writing on a busy site. I have written a following code which eventually end up freezing 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 can't use LOCK_NB because it will not work on windows. The code works fine if there are less than 13 processes execute the above code at the same. How do I cope with this deadlock situation?

like image 655
Maximus Avatar asked Oct 11 '22 05:10

Maximus


2 Answers

Reading your code, I'm thinking you should move flock($handler, LOCK_UN); inside the if (flock($handler, LOCK_EX)) {} conditional block.

To figure out exactly what's getting stuck and where, I would add datestamped (and flushed, so nothing gets stuck in the output buffer) debug output both before and after each call to flock(), fopen(), fwrite(), and fclose(), and redirect the output from each script instance to its own file.

Then, after a freeze + restart you can review the end of each file and see what each script was doing when you restarted. By comparing the datestamps you should be able to see which script(s) "froze" first.

like image 135
Peter Avatar answered Oct 18 '22 10:10

Peter


Hy

Try with file_put_contents():

<?php

$file = 'file.txt';

$str = "some text\n";

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

?>

like image 42
CoursesWeb Avatar answered Oct 18 '22 10:10

CoursesWeb