ホームページ >バックエンド開発 >PHPチュートリアル >crond スクリプト実行時の同時実行性の競合を解決するにはどうすればよいですか?
計画されたタスクでは、繰り返し実行されることがあります:
たとえば、当社の計画されたタスク:
*/2 * * * * root cd /opt/xxxx/test_S1/html/xxxx/admin; php index.php task testOne >/dev/null 2>&1*/2 * * * * root cd /opt/xxxx/test_S1/html/xxxx/admin; php index.php task testTwo >/dev/null 2>&1
これは 2 分に 1 回実行されるタスクです。毎回開始されるプロセスが実行されるという保証はありません。実行は 2 分以内に完了し、プロセスが蓄積し続けるとシステム リソースが枯渇し、システムがクラッシュする可能性があります。
例:
次のコードで新しいtest.phpファイルを作成します:
<?php sleep(70);?>
スケジュールされたタスクを追加します:
*/1 * * * * root cd /home/ganjincheng;php test.php
実行を待っていると蓄積が発生します
root 26722 0.0 0.0 9232 1064 ? Ss 12:05 0:00 /bin/sh -c cd /home/ganjincheng;php test.php root 26744 0.0 0.0 112304 8840 ? S 12:05 0:00 php test.php root 29102 0.0 0.0 9232 1060 ? Ss 12:06 0:00 /bin/sh -c cd /home/ganjincheng;php test.php root 29116 0.1 0.0 112304 8840 ? S 12:06 0:00 php test.php root 29906 0.0 0.0 103320 904 pts/3 S+ 12:06 0:00 grep test.php
このメソッドはコードを変換します。プロセス実行の有無の判定を追加します。たとえば、次のコード:
<?php $lockfile = '/tmp/mytest.lock'; if(file_exists($lockfile)){ exit(); } file_put_contents($lockfile, date("Y-m-d H:i:s")); sleep(70); unlink($lockfile); ?>
ファイルが存在するかどうかを判断するこの方法には問題があります。つまり、プログラムが最後まで実行されていない、つまり以前に作成した mytest.lock ファイルが削除されていない可能性があります。これにより、将来的にプログラムが適切に実行できなくなります。
最初のソリューションは、キー値の判断のために Redis と memache に転送できます。
スケジュールされたタスクがデータベースにアクセスするものである場合、テーブル ロック操作を実行できます。場合によっては、一意のインデックスとジョイント インデックスの一意性を利用して、繰り返しの挿入を回避することもできます
例:
$fp = popen("ps aux | grep 'test.php' | wc -l", "r"); $proc_num = fgets($fp);if ($proc_num > 3) { //这里要注意为什么进程数要大于3,实际操作一遍你就明白了exit; } sleep(70);
この方法には欠点があります。 ps コマンドは正確に記述する必要があります。 test.php スクリプトを実行していないプロセスをカウントしないようにします。例:
vim を介して test.php ファイルを開きます。これにより、上記のコマンドが正しくカウントされなくなります。そのため、誤って test.php ファイルを vim で開いた場合、そのファイルは実行できません。
Linuxに判断を手伝ってもらいます。 flockコマンドはファイルロック機能を提供します。コマンドパラメータは以下の通りです:
[root@qkzj_Multi-Purpose_1A_113.107.248.124 ganjincheng]# flock -h flock (util-linux-ng 2.17.2) Usage: flock [-sxun][-w #] fd# flock [-sxon][-w #] file [-c] command... flock [-sxon][-w #] directory [-c] command... -s --shared Get a shared lock -x --exclusive Get an exclusive lock -u --unlock Remove a lock -n --nonblock Fail rather than wait -w --timeout Wait for a limited amount of time -o --close Close file descriptor before running command -c --command Run a single command string through the shell -h --help Display this text -V --version Display version
設定例:
*/1 * * * * root flock -xn /tmp/mytest.lock -c 'php ./test.php'
以上がcrond スクリプト実行時の同時実行性の競合を解決するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。