ホームページ > バックエンド開発 > PHPチュートリアル > crond で flock コマンドを使用する際の落とし穴

crond で flock コマンドを使用する際の落とし穴

WBOY
リリース: 2016-06-23 09:09:34
オリジナル
1166 人が閲覧しました

現象

PHP スクリプトを定期的に実行する必要がある最初に思いつくのは、crond コマンドでこの機能を実装することです。しかし、クロンの処刑中に奇妙なことが判明した。 crondでの設定は以下の通りです。

*/1 * * * * root /usr/bin/flock -xn /tmp/test.lock -c '/usr/bin/php /home/hailong/test.php > /tmp/test.tt 2>&1'
ログイン後にコピー

スクリプトは初回のみ正常に実行され、再度実行されることはありません。 /tmp/test.lock ファイルを削除すると、PHP スクリプトは再び正常に実行できるようになります。一度実行すると再度正常に実行することはできません。

余談:

ご覧のとおり、設定ファイルの最後に 2>&1 が追加されています。なぜ 2>&1 を追加するのでしょうか?ブログ投稿「エコーによるプロセスクラッシュ」をチェックしてください

さらに、注意深い友人なら、flock コマンドを使用したことにも気づくでしょう。 flock コマンドは、スクリプトが同時に繰り返し実行されるのを防ぐために使用されます。 crond スクリプトの同時実行および繰り返し実行を制御するその他の方法については、「Crond スクリプト実行における同時実行競合の解決」を参照してください。

分析

crond 設定から flock を削除します。以下の通り:

*/1 * * * * root /usr/bin/php /home/hailong/test.php > /tmp/test.tt 2>&1
ログイン後にコピー

スクリプトが正常に実行できることがわかりました。それはフロックの問題に違いない。 flock は成熟した Linux コマンドなので、問題が発生する可能性はほとんどありません。最も可能性として考えられるのは、PHP コードの一部が flock と競合していることです。 PHP コードは次のとおりです。

<?php$f = popen("/home/exfilter restart", "r");while(!feof($f)) {    $content = fgets($f, 1024);    if (strpos($content, "start success") !== false) {        break;    }}pclose($f);file_put_contents("/tmp/test.log", date("Y-m-d H:i:s"));?>
ログイン後にコピー

前にも言いましたが、初回のみ flock のロック ファイルが存在しないため、正常に実行できます。ロックファイルが存在すると正常に実行されなくなります。 PHP プログラムの実行後、flock はファイルのロックを解放しません。 /tmp/test.lock ファイルがどのファイルによって占有されているかを見てみましょう。

[hailong@vhost ~]$ sudo /usr/sbin/lsof | grep test.lockexfilter  29821        root    3r      REG              202,1           0   90439710 /tmp/test.lock[hailong@vhost ~]$ ps aux | grep 29821root     29821  0.1  0.2 175224 22596 ?        Ssl  07:46   0:00 /home/exfilter -d56667    30068  0.0  0.0  69460   852 pts/0    S+   07:49   0:00 grep 29821
ログイン後にコピー

test.lock ファイルが、PHP プログラムの Popen 関数によって開始されたプロセスによって占有されていることがわかります。デーモンプロセスが起動されるため、プロセスは終了せず、常にロックが占有されます。

解決策

flock コマンドを有効にして、代わりに他の方法を使用してください。その他の方法については、ブログ投稿「Crond スクリプト実行における同時実行競合の問題の解決」を参照してください。

詳細情報

Linux システム上のファイル ロックは、主に勧告ロックと必須ロックに分けられます。 Linux で使用されるファイル ロックのほとんどは協調ロックであり、強制ロックを使用する場合は、システムが強制ロックをサポートしているかどうかも確認する必要があります

協調ロックでは、ロックが機能する前にユーザー プロセスがファイル ロックを積極的に適用する必要があります。たとえば、プロセス A がファイルに協調ロックを追加した場合、プロセス B がロックを適用せずにファイルに直接書き込む場合にも可能です。

強制ロックはオペレーティング システム カーネルによって保証されています。ユーザープロセスが独自に申請する必要はありません。

flock コマンドは協調ロックを使用します。

メインプロセスがファイルロックを取得すると、フォークされた子プロセスもファイルロックを取得します。

元のリンク: crond で flock コマンドを使用する場合の落とし穴、転載する場合は出典を明示してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート