Распространяется ли flock () только на текущий метод?

Ли flock() Функция работает, только если она используется в том же методе, что и код?

Например, в следующем коде блокировка успешна:

public function run()
{
$filePointerResource = fopen('/tmp/lock.txt', 'w');
if (flock($filePointerResource, LOCK_EX)) {
sleep(10);
} else {
exit('Could not get lock!');
}
}

Однако в следующем коде блокировка не удалась:

public function run()
{
if ($this->lockFile()) {
sleep(10);
} else {
exit('Could not get lock!');
}
}

private function lockFile()
{
$filePointerResource = fopen('/tmp/lock.txt', 'w');
return flock($filePointerResource, LOCK_EX);
}

Я не видел никакой документации по этому вопросу, поэтому я озадачен этим поведением. Я использую PHP версии 5.5.35.

1

Решение

Я думаю, что проблема с вашей попыткой на основе класса заключается в том, что когда lockFile метод заканчивает $filePointerResource выходит из области видимости, и это, вероятно, то, что снимает блокировку

Это работает, что поддерживает эту теорию

<?php

class test {
public function run()
{
$fp = fopen('lock.txt', 'w');
if ($this->lockFile($fp)) {
echo 'got a lock'.PHP_EOL;
sleep(5);
}
/*
* Not going to do anything as the attempt to lock EX will
* block until a lock can be gained

else {
exit('Could not get lock!'.PHP_EOL);
}
*/
}

private function lockFile($fp)
{
return flock($fp, LOCK_EX);
}
}

$t = new test();
$t->run();

Поэтому, если вы хотите заблокировать файл более чем одним вызовом метода класса, может быть лучше сохранить дескриптор файла как свойство класса, тогда он останется в области действия, пока создается экземпляр класса и в области действия.

<?php

class test {
private $fp;

public function run()
{
$this->fp = fopen('lock.txt', 'w');
if ($this->lockFile()) {
echo 'got a lock'.PHP_EOL;
sleep(5);
}
/*
* Not going to do anything as the attempt to lock EX will
* block until a lock can be gained

else {
exit('Could not get lock!'.PHP_EOL);
}
*/
}

private function lockFile()
{
return flock($this->fp, LOCK_EX);
}
}

$t = new test();
$t->run();
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]