日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

php flock 超时,php flock失效问题

發(fā)布時間:2025/4/16 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php flock 超时,php flock失效问题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

這兩天給自己的業(yè)余項(xiàng)目寫了一個方法,用來避免crontab調(diào)度的PHP腳本并發(fā)執(zhí)行。

做法

一般通過使用文件鎖flock方法,令相同的PHP腳本采用非阻塞鎖同一個磁盤文件,如果文件被占用則會報錯,從而可以腳本立即退出。

現(xiàn)象

但實(shí)踐中發(fā)現(xiàn),在controller文件中直接flock是可以實(shí)現(xiàn)的,當(dāng)把flock的邏輯封裝到其他文件的一個函數(shù)中后就失效了。

原因

調(diào)試了半天,突然想起來以前就遇到過這個神坑。。

錯誤代碼如下:

PHP

class Crontab

{

/**

* 確保任務(wù)沒有并發(fā)執(zhí)行

*/

public static function isRunning() {

global $argv;

$ident = [];

foreach ($argv as $idx => $value) {

$ident[] = $idx . '=' . urlencode($value);

}

$ident = md5(implode('&', $ident));

$lockDir = \Yii::getAlias('@app/runtime/crontab/');

@mkdir($lockDir, 0755, true);

$file_lock = fopen($lockDir . $ident, 'w+');

$wouldBlock = 0;

flock($file_lock, LOCK_EX | LOCK_NB, $wouldBlock);

return $wouldBlock;

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

classCrontab

{

/**

* 確保任務(wù)沒有并發(fā)執(zhí)行

*/

publicstaticfunctionisRunning(){

global$argv;

$ident=[];

foreach($argvas$idx=>$value){

$ident[]=$idx.'='.urlencode($value);

}

$ident=md5(implode('&',$ident));

$lockDir=\Yii::getAlias('@app/runtime/crontab/');

@mkdir($lockDir,0755,true);

$file_lock=fopen($lockDir.$ident,'w+');

$wouldBlock=0;

flock($file_lock,LOCK_EX|LOCK_NB,$wouldBlock);

return$wouldBlock;

}

}

根據(jù)命令行參數(shù)生成唯一hash值,代表該P(yáng)HP任務(wù)。

創(chuàng)建鎖文件,執(zhí)行flock非阻塞鎖,返回wouldBlock標(biāo)識鎖是否已被占用。

我在腳本入口調(diào)用了Crontab::isRunning()方法,發(fā)現(xiàn)并發(fā)啟動腳本后,總是能獲得鎖。

錯誤原因是:isRunning()方法退出后,$file_lock沒有繼續(xù)使用,被PHP垃圾回收,$fp文件句柄關(guān)閉導(dǎo)致鎖自動釋放。

解決

PHP

class Crontab

{

/**

* 保存起來避免被php作為垃圾回收

* @var null

*/

static $file_lock = null;

/**

* 確保任務(wù)沒有并發(fā)執(zhí)行

*/

public static function isRunning() {

global $argv;

$ident = [];

foreach ($argv as $idx => $value) {

$ident[] = $idx . '=' . urlencode($value);

}

$ident = md5(implode('&', $ident));

$lockDir = \Yii::getAlias('@app/runtime/crontab/');

@mkdir($lockDir, 0755, true);

self::$file_lock = fopen($lockDir . $ident, 'w+');

$wouldBlock = 0;

flock(self::$file_lock, LOCK_EX | LOCK_NB, $wouldBlock);

return $wouldBlock;

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

classCrontab

{

/**

* 保存起來避免被php作為垃圾回收

* @var null

*/

static$file_lock=null;

/**

* 確保任務(wù)沒有并發(fā)執(zhí)行

*/

publicstaticfunctionisRunning(){

global$argv;

$ident=[];

foreach($argvas$idx=>$value){

$ident[]=$idx.'='.urlencode($value);

}

$ident=md5(implode('&',$ident));

$lockDir=\Yii::getAlias('@app/runtime/crontab/');

@mkdir($lockDir,0755,true);

self::$file_lock=fopen($lockDir.$ident,'w+');

$wouldBlock=0;

flock(self::$file_lock,LOCK_EX|LOCK_NB,$wouldBlock);

return$wouldBlock;

}

}

確保在整個PHP生命期內(nèi),文件句柄都不會被釋放即可,所以保存在類靜態(tài)成員變量里。

如果文章幫助您解決了工作難題,您可以幫我點(diǎn)擊屏幕上的任意廣告,或者贊助少量費(fèi)用來支持我的持續(xù)創(chuàng)作,謝謝~

總結(jié)

以上是生活随笔為你收集整理的php flock 超时,php flock失效问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。