Reputation: 1216
Hi I have a php function it takes about 20 min (or more) to run and finish.
but if somebody else run it during last run...The function break with unwanted result.
this is the structures:
function myfunc()
{
foreach()
{
//do somthing
}
}
I think I can do it via a file like this:
I created a text file ... if content of that text was '1',the function is lock. if not the function is free.
function myfunc()
{
$file = "lock.txt";
$f = fopen($file, 'r');
$line = fgets($f);
fclose($f);
if($line == 0)
file_put_contents($file, "1");
else
return false;
foreach()
{
}
//after finish for each
file_put_contents($file, "0"); // free function for other user
}
I think logically it must be true ...but do not work! after first run, the content of lock.txt file remain 1. (not change to 0 after finish)
I think maybe the function breaks during process becuase of long times! because I handle all break state in function. can tel me how can handle this problem? how can I be sure that lock.txt will be '0' after finish or break function?
Upvotes: 3
Views: 2724
Reputation: 1
I use these functions (I call them my_lock and my_unlock for example):
function my_lock($name) {
$lockFile = 'myfolder/' . $name . '.lck';
$lock = fopen($lockFile, 'w');
if (!$lock) {
return false;
}
if (flock($lock, LOCK_EX)) {
return $lock;
} else {
fclose($lock);
return false;
}
}
function my_unlock($lock) {
if ($lock !== false) {
flock($lock, LOCK_UN);
fclose($lock);
}
}
example of use:
$lock = my_lock('hello_world');
if ($lock === false) {
throw new Exception('Lock error');
}
try {
//... your locked code here ...
} finally {
my_unlock($lock);
}
Upvotes: 0
Reputation: 1216
Thanks my friends for the answer..
I couldn't run your code...maybe bcause I can not config them well...
but I solved my problem with insert function insile code like this:
$file = "lock.txt";
$f = fopen($file, 'r');
$line = fgets($f);
fclose($f);
if($line == 0)
{
file_put_contents($file, "1");
myfunction();
file_put_contents($file, "0");
}
else
{
echo "Already running.";
}
hope help sombody else...
Upvotes: 0
Reputation: 18550
By far the best way in my experience is similar to this
<?php
define('LOCK_FILE', "/var/run/" . basename($argv[0], ".php") . ".lock");
if (!tryLock())
die("Already running.\n");
# remove the lock on exit (Control+C doesn't count as 'exit'?)
register_shutdown_function('unlink', LOCK_FILE);
# The rest of your script goes here....
echo "Hello world!\n";
sleep(30);
exit(0);
function tryLock()
{
# If lock file exists, check if stale. If exists and is not stale, return TRUE
# Else, create lock file and return FALSE.
if (@symlink("/proc/" . getmypid(), LOCK_FILE) !== FALSE) # the @ in front of 'symlink' is to suppress the NOTICE you get if the LOCK_FILE exists
return true;
# link already exists
# check if it's stale
if (is_link(LOCK_FILE) && !is_dir(LOCK_FILE))
{
unlink(LOCK_FILE);
# try to lock again
return tryLock();
}
return false;
}
?>
Taken from comments of
http://php.net/manual/en/function.getmypid.php
This locks to the process so if the process fails you can remove the lock
Upvotes: 0
Reputation: 1745
Well there is already a function to implement lock Called flock()
<?php
$file = fopen("test.txt","w+");
// exclusive lock
if (flock($file,LOCK_EX))
{
fwrite($file,"Write something");
// release lock
flock($file,LOCK_UN);
}
else
{
echo "Error locking file!";
}
fclose($file);
?>
using a flag LOCK_SH you can lock it
Upvotes: 1