ホームページ  >  記事  >  バックエンド開発  >  PHP プログラムでファイル ロック、ミューテックス ロック、読み取り/書き込みロックを使用するためのヒントの分析、_PHP チュートリアル

PHP プログラムでファイル ロック、ミューテックス ロック、読み取り/書き込みロックを使用するためのヒントの分析、_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-12 08:56:12945ブラウズ

PHP プログラムでファイル ロック、ミューテックス ロック、読み取り/書き込みロックを使用するためのヒントの分析、

ファイル ロック
正式名称はアドバイザリーファイルロックで、書籍内で言及されています。 このタイプのロックは比較的一般的です。たとえば、mysql と php-fpm が開始された後、プロセス ID を記録する pid ファイルが作成されます。このファイルはファイル ロックです。

このロックにより、プロセスが繰り返し実行されるのを防ぐことができます。たとえば、crontab を使用する場合、1 つのタスクは 1 分ごとに実行されるように制限されますが、プロセス ロックを解決するために使用されない場合、このプロセスの実行時間は 1 分を超える可能性があります。競合するため、2 つのプロセスを一緒に実行すると問題が発生します。

PID ファイル ロックを使用するもう 1 つの利点は、プロセスが停止信号または再起動信号をそれ自体に送信するのに便利であることです。たとえば、php-fpm を再起動するコマンドは

です。

kill -USR2 `cat /usr/local/php/var/run/php-fpm.pid`
pid ファイルに記録されているプロセスに USR2 シグナルを送信します。このシグナルはプロセス通信に属しており、別の章で説明します。

phpのインターフェースはflockであり、ドキュメントは比較的詳細です。まず定義を見てみましょう、 bool flock ( resource $handle , int $operation [, int &$wouldblock ] )。

  • $handle はファイル システム ポインターであり、通常は fopen() によって作成されるリソースです。これは、flock を使用するにはファイルを開く必要があることを意味します。
  • $operation は操作の種類です。
  • &$wouldblock ロックがブロックされている場合、この変数は 1 に設定されます。

この関数はデフォルトでブロックしていることに注意してください。ブロックしないようにするには、ビットマスク LOCK_NB を操作に追加します。

リーリー

それを process.php として保存し、php process.php & を実行してから、php process.php を再度実行すると、エラー メッセージが表示されます。 flock には共有ロック LOCK_SH もあります。

ミューテックスロックと読み書きロック
同期モジュールのミューテックス:
Mutex は、相互排除を意味する複合語です。 pecl を使用して同期モジュール (pecl install sync) をインストールします。 ドキュメント内の SyncMutex には、lock と lock の 2 つのメソッドしかありません。コードのテストに直接進みましょう。 IDE で書いたわけではないので、cs は非常に見苦しいですが、無視してください。

リーリー

mutex.phpとして保存し、php mutex.phpを実行すると、出力は

リーリー

ここで、サブプロセス 0 と 1 は必ずしも前にあるわけではありません。しかし、ロックを取得できない人が常に存在します。ここでの SyncMutex::lock(int $millisecond) のパラメータはミリ秒で、ブロック期間を表し、-1 は無限ブロックを意味します。

同期モジュールの読み取り/書き込みロック:
SyncReaderWriter のメソッドも同様で、readlock、readunlock、writelock、writeunlock がペアで表示されます。テスト コードは記述されていません。Mutex コードと一致している必要があり、ロックを置き換えるだけです。

同期モジュールのイベント:
golang の Cond に似た感じで、wait() がブロックし、fire() が Event によってブロックされたプロセスを起動します。 Cond を紹介する良い記事があります。Cond がロックの固定的な使用法であることがわかります。 SyncEvent についても同様です。
PHP ドキュメントの例では、fire() メソッドが Web アプリケーションで使用されているようです。

テストコードをアップロードする

リーリー

ここで意図的に書かれている fire() が 1 つ少ないため、プログラムはブロックされます。これは、 fire() が一度に 1 つのプロセスのみを起動することを証明しています。

pthreadsモジュール
ミューテックスのロックとロック解除:

機能:

リーリー

使用法:

スレッドは pthread_mutex_lock() 関数を使用して、指定されたミューテックス変数をロックします。ミューテックスがすでに別のスレッドによってロックされている場合、この呼び出しはミューテックスのロックが解除されるまでスレッドをブロックします。
pthread_mutex_trylock() はミューテックスをロックしようとしますが、ミューテックスがすでにロックされている場合、ルーチンはすぐに「ビジー」エラー コードを返します。このルーチンは pthread_mutex_trylock() で役立つ場合があります。

ミューテックスをロックしようとしましたが、ミューテックスがすでにロックされている場合、プログラムはすぐに戻り、ビジーエラー値を返します。この機能は、優先度変更時のデッドロックを防ぐのに役立ちます。スレッドは pthread_mutex_unlock() を使用して、スレッドが占有しているミューテックスのロックを解除できます。この関数は、1 つのスレッドが保護されたデータの使用を完了し、他のスレッドが保護されたデータを処理するためにミューテックスを取得する必要があるときに呼び出すことができます。以下の状況が発生した場合、エラーが発生します:

    ミューテックスのロックが解除されました
  • ミューテックスは別のスレッドによって占有されています
ミューテックスには「魔法」は何もありません。実際、ミューテックスは参加しているスレッドの「紳士協定」です。コードを記述するときは、必ずミューテックスを正しくロックおよびロック解除してください。

Q: 同じロックされたミューテックスを待機しているスレッドが複数あります。ミューテックスがロック解除されると、どのスレッドが最初にミューテックスをロックしますか?

A: スレッドが優先スケジューリング メカニズムを使用しない限り、スレッドはシステム スケジューラによって割り当てられ、最初にミューテックスをロックするスレッドはランダムです。

リーリー

セマフォ 同期モジュールのセマフォ:

SyncSemaphore ドキュメントには、それと Mutex の違いは、セマフォは一度に複数のプロセス (またはスレッド) によって取得できるのに対し、ミューテックスは一度に 1 つしか取得できないことであることが示されています。そのため、SyncSemaphore のコンストラクターには、セマフォを何プロセスで取得できるかを指定するパラメーターがあります。
public SyncSemaphore::__construct ([ string $name [, integer $initialval [, bool $autounlock ]]] ) は、この $initialval (初期値) です
リーリー

現時点では、両方のプロセスがロックを取得できます。

  • sysvsem模块中的信号量
  • sem_get 创建信号量
  • sem_remove 删除信号量(一般不用)
  • sem_acquire 请求得到信号量
  • sem_release 释放信号量。和 sem_acquire 成对使用。
$key = ftok('/tmp', 'c');

$sem = sem_get($key);

for($i=0; $i<2; $i++){
  $pid = pcntl_fork();
  if($pid <0){
    die("fork failed");
  }elseif ($pid>0){
    //echo "parent process \n";
  }else{
    echo "child process {$i} is born. \n";
    obtainLock($sem, $i);
  }
}

while (pcntl_waitpid(0, $status) != -1) { 
  $status = pcntl_wexitstatus($status); 
  echo "Child $status completed\n"; 
}
sem_remove($sem); // finally remove the sem

function obtainLock ($sem, $i){
  echo "process {$i} is getting the sem \n";
  $res = sem_acquire($sem, true);
  sleep(1);
  if (!$res){
    echo "process {$i} unable to get sem. \n";
  }else{
    echo "process {$i} successfully got the sem \n";
    sem_release($sem);
  }
  exit();
}

这里有一个问题,sem_acquire()第二个参数$nowait默认为false,阻塞。我设为了true,如果得到锁失败,那么后面的sem_release会报警告 PHP Warning:  sem_release(): SysV semaphore 4 (key 0x63000081) is not currently acquired in /home/jason/sysvsem.php on line 33, 所以这里的release操作必须放在得到锁的情况下执行,前面的几个例子中没有这个问题,没得到锁执行release也不会报错。当然最好还是成对出现,确保得到锁的情况下再release。
此外,ftok这个方法的参数有必要说明下,第一个 必须是existing, accessable的文件, 一般使用项目中的文件,第二个是单字符字符串。返回一个int。

输出为

parent process 
parent process 
child process 1 is born. 
process 1 is getting the mutex 
child process 0 is born. 
process 0 is getting the mutex 
process 1 successfully got the mutex 
Child 0 completed
process 0 unable to lock mutex. 
Child 0 completed

您可能感兴趣的文章:

  • php session的锁和并发
  • PHP使用flock实现文件加锁的方法
  • PHP session文件独占锁引起阻塞问题解决方法
  • PHP中使用Memache作为进程锁的操作类分享
  • PHP对文件进行加锁、解锁实例
  • PHP文件锁函数flock()详细介绍
  • PHP通过插入mysql数据来实现多机互锁实例
  • PHP文件锁定写入实例解析
  • PHP 解决session死锁的方法
  • PHP flock 文件锁详细介绍
  • 并发下常见的加锁及锁的PHP具体实现代码
  • phplock(php进程锁) v1.0 beta1
  • PHP 进程锁定问题分析研究
  • PHP下通过系统信号量加锁方式获取递增序列ID

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1113732.htmlTechArticlePHP程序中的文件锁、互斥锁、读写锁使用技巧解析, 文件锁 全名叫 advisory file lock, 书中有提及。 这类锁比较常见,例如 mysql, php-fpm 启动之...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。