ホームページ >バックエンド開発 >PHPチュートリアル >PHPにおけるファイルロックとプロセスロックの使用例を詳しく解説

PHPにおけるファイルロックとプロセスロックの使用例を詳しく解説

黄舟
黄舟オリジナル
2017-08-08 09:18:271167ブラウズ

この記事では主にPHPのファイルロックとプロセスロックの使用例を紹介していますが、編集者が非常に良いと思ったので、参考として共有します。先ほどの swoole の紹介を踏まえて、swoole のサーバー/クライアントとマルチプロセスの仕組みを使ってロックについて説明しましょう


ここでは、PHP のロック機構についてのみ説明します。 SQL のロック その動作モードとアプリケーションのシナリオは異なるため、個別に説明します

flock()

    fclose()
  • swoole_lock()
  • ファイル ロック 考えられるアプリケーション シナリオは次のとおりです。
  • 1. 同じファイルにアクセスして変更する必要がある同時の複数のプロセスまたは複数のサーバーを制限します。

2. ファイル I/O に参加するプロセスのキューイングと人為的なブロック。

3 .ビジネスロジックでファイルの内容を保護します。

以下はファイルロックC/S通信メカニズムの使用であり、特定の通信プロセスは省略されています

サーバー(サーバー通信プロセスは省略されています) ):


//监听数据发送事件
$serv->on('receive', function ($serv, $fd, $from_id, $data) {
  $serv->send($fd, "ServerEnd");

  $p_file = "locktest.txt";
  var_dump(file_get_contents($p_file));
});

Client1 (サーバー通信処理を省略):


$s_recv = "ww";

$p_file = "locktest.txt";

$o_file = fopen($p_file,'w+');
// flock()加锁方式:
flock($o_file,LOCK_EX);

// // swoole加锁方式:
// $lock = new swoole_lock(SWOOLE_FILELOCK, $p_file);
// $lock->lock();

fwrite($o_file, 'ss' . $s_recv);

sleep(30);
// 两种解锁方式
// flock($o_file, LOCK_UN);
// $lock->unlock();

Client2 (サーバー通信処理を省略):


$s_recv = "xx";

$p_file = "locktest.txt";

$o_file = fopen($p_file,'w+');
// flock()加锁方式:
flock($o_file,LOCK_EX);

// // swoole加锁方式:
// $lock = new swoole_lock(SWOOLE_FILELOCK, $p_file);
// $lock->lock();


fwrite($o_file, 'ss' . $s_recv);

// 两种解锁方式
// flock($o_file, LOCK_UN);
// $lock->unlock();

結果:

Client2がブロックされました30 秒間、Client1 の実行が完了するまでファイルは処理されませんでした。


[l0.16@4 m29.5% c30s04] $ php swoole_client2.php

次の点に注意してください:

1. flock() または swoole が提供する swoole_lock() 。プロセス終了時に自動的にロックを解除する仕組みなので、デモで使用しなくても手動でのロック解除も正常に実行できるため、最初のクライアントでsleep()の一時停止関数を実行してファイルロックの効果を観察します。


2. flock() の標準的な解放方法は flock($file, LOCK_UN) ですが、個人的には将来のトラブルを避けるために fclose() を好みます;


2. プロセスロック


とは異なります。ファイル ロック、プロセス ロックは、ファイルへの I/O を防止するためには使用されません。したがって、複数のプロセスが同時実行される場合は、複数のプロセスをキューに入れる必要があります。つまり、他の同時実行のロジック実行をブロックする必要があります。プロセスのキー ロジックの実行が終了する前にプロセスを実行します。 いくつかの実装アイデアがあります:

1. flock() ファイル ロックを使用して一時ロック ファイルを作成し、LOCK_NB を使用してブロッキング フローまたはノンブロッキング フローをシミュレートします。次に、判定条件を使用してプロセス内のロジックの実行を制御します。

ノンブロッキング モデルのデモ:

$p_file = "locktest.txt";
$o_file = fopen($p_file, 'w+');

// 如果临时文件被锁定,这里的flock()将返回false
if (!flock($o_file, LOCK_EX + LOCK_NB)) {
  var_dump('Process Locked');
}
else {
  // 非阻塞模型必须在flock()中增加LOCK_NB参数
  // 当然,这里取消LOCK_NB参数就是阻塞模型了
  flock($o_file, LOCK_EX + LOCK_NB);
  var_dump('Process Locking');
  // 模拟长时间的执行操作
  sleep(10);
}

2. swoole が提供する共有メモリ、キャッシュ方法、または通信方法を使用して、異なるプロセスでグローバル変数を渡します。プロセスは変数のステータスを取得した後、判定条件を使用してロジックの実行を制御します

変数を渡す方法はたくさんありますが、ここではアイデアを提供するために、


ブロッキング モデルのデモを取り上げます。


// 初始化memcached
$memcached = new Memcache;
$memcached->connect("localhost", 11211);

// 获取用来做状态判定的全局变量
$s_flag = $memcached->get("flag");

if (!$s_flag) {
  // 这里利用了memcached的过期时间作为演示,实际上业务处理完成后销毁该变量即可
  $memcached->set("flag", "locked", 0, 10);
  main();
}
else {
  // 阻塞模型
  while ($s_flag == 'locked') {
    var_dump('Process locked, retrying...');
    // 设置重试时间, 避免过于频繁的操作尝试
    sleep(1);
    // 更新状态变量
    $s_flag = $memcached->get("flag");
  }
  // // 非阻塞模型
  // if ($s_flag == 'locked') {
  //   var_dump('Process locked, suspended');
  //   die();
  // }
  main();
}

// 模拟业务主函数
function main() {
  var_dump('Process Running');
  // 业务执行结束后回收memcached
  // $memcached->delete("flag");
}

ここで注意する必要があるのは:


1. memcached の有効期限は実際のプログラムの実行時間よりも短くすることはできないため、少し長くしてロジックの後でリサイクルすることをお勧めします。実行が完了します。

2. 非ブロッキング モデルでは、ステータスが false と判断された場合、ビジネス ロジックの継続実行を回避するためにプロセスを終了するかブロックする必要があります。アプリケーションでは、再試行時間を設定する必要があります。これにより、memcached の大量の I/O 同時実行性が大幅に削減され、サーバーの負荷が軽減されます。

以上がPHPにおけるファイルロックとプロセスロックの使用例を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。