2011-02-05 16 views
0

PHPファイルを作成しようとしていますが、すでに実行中の場合は実行されません。私が使用しているコードは次のとおりです。PHPでファイルをロックするには?

<?php 

class Test { 
    private $tmpfile; 

    public function action_run() { 
     $this->die_if_running(); 
     $this->run(); 
    } 

    private function die_if_running() { 
     $this->tmpfile = @fopen('.refresher2.pid', "w"); 

     $locked = @flock($this->tmpfile, LOCK_EX|LOCK_NB); 
     if (! $locked) { 
      @fclose($this->tmpfile); 
      die("Running 2"); 
     } 
    } 

    private function run() { 
     echo "NOT RUNNNING"; 
     sleep(100); 
    } 
} 

$test = new Test(); 
$test->action_run(); 

問題は、コンソールからこれを実行すると素晴らしいことです。しかし、私はそれをブラウザから実行しようとすると、多くのインスタンスが同時に実行できます。これは、Windows 7、XAMPP、PHP 5.3.2にあります。 OSはそれが同じプロセスであると考えているため、機能が低下すると思います。このタイプのPHPスクリプトを作成するためのクロスプラットフォームの方法はありますか?

+1

LOCK_NBはWindowsではサポートされていません。無音演算子(@)を使用することは本当に悪い考えです。実際には、あなたが得ているエラーを抑制しているかもしれません。 – Evert

+0

@Evert、提案のおかげで、私はロックコードをコピーしましたが、@は削除されませんでしたが、エラーは表示されません。 – Fluffy

答えて

0

有望なものはありません。あなたはこれのために群れを使うことはできません。

system()を使用して、ロックを行う別の(php)プロセスを開始できます。しかし、欠点:

  • プロセス間通信が必要です。どのように他のプログラムにロックなどを解放するかを伝える方法を考えてください。あなたは3つの定数や何かを使いこなすためにstdinを使うことができます。この場合、やや単純です。
  • 高価なプロセスを作成し続けるため、パフォーマンスが悪いです。

もう1つの方法は、常に実行される別のプログラムを起動することです。あなたはIPCのいくつかの手段を使用して(それはクロスプラットフォームなのでおそらくちょうどtcpチャンネルを使用して)接続し、このプログラムがファイルへのアクセスを管理できるようにします。そのプログラムは無限ループのPHPスクリプトでもありますが、これをJavaやマルチスレッド対応の別の言語で記述する方が簡単かもしれません。

もう1つの方法は、既存のリソースを活用することです。ロック用のダミーのデータベーステーブルを作成し、ファイルのエントリを作成してから、テーブルローロックを実行します。

別の方法は、ファイルを使用するのではなく、データベースを使用することです。

+0

@Downvoter:これは何が問題なのですか?あなたがそれを投票した場合、少なくとも理由をコメントする必要があります! – yankee

+0

私はmysqlのロックを使用しようとしますね、ありがとう – Fluffy

0

もう少し前に同様の問題がありました。 返される番号が一意のカウンタを持つ必要がありました。 ロックファイルを使用しましたが、このインスタンスが現在の番号でファイルを読み取ることが許可されていた場合にのみロックファイルを作成できました。

おそらくカウントアップする代わりに、スクリプトの実行を許可することができます。 トリックは、小さなウェイト/スリープを数回(5人など)試してみることです。

function GetNextNumber() 
{ 
    $lockFile = "lockFile.txt"; 
    $lfh = @fopen($lockFile, "x"); 
    if (!$lfh) 
    { 
    $lockOkay = false; 
    $count = 0; 
    $countMax = 5; 

    // Try ones every second in 5 seconds 
    while (!$lockOkay & $count < $countMax) 
    { 
     $lfh = @fopen($lockFile, "x"); 
     if ($lfh) 
     { 
     $lockOkay = true; 
     } 
     else 
     { 
     $count++; 
     sleep(1); 
     } 
    } 
    } 

    if ($lfh) 
    { 
    $fh = fopen($myFile, 'r+') or die("Too many users. "); 
    flock($fh, LOCK_EX); 
    $O_nextNumber = fread($fh, 15); 
    $O_nextNumber = $O_nextNumber + 1; 
    rewind($fh); 
    fwrite($fh, $O_knr); 
    flock($fh, LOCK_UN); 
    fclose($fh); 

    unlink($lockFile); // Sletter lockfilen 
    } 

    return $O_nextNumber; 
} 
関連する問題