検索
ホームページphp教程php手册PHP文件锁用法详解

PHP文件锁用法详解

Jun 13, 2016 am 10:16 AM
mysqlphpそして現れる書類持っている使用法テーブルロック詳しい説明ロック

PHP出现文件锁与mysql表锁有大概想的用法,就是同一时间只能让一个人操作,这样就避免了同时有多个人操作同一文件,这样导致数据丢失的情况了,下面我来给大家介绍PHP文件锁用法。

PHP自带了文件锁函数:
bool flock ( int $handle , int $operation [, int &$wouldblock ] )
$handle 是打开的文件指针;
$operation 可以是
“LOCK_SH”,共享锁定;“LOCK_EX”,独占锁定;“LOCK_UN”,释放锁定;“LOCK_NB”,防止flock锁定时堵塞。
这里主要说说“LOCK_EX”和“LOCK_NB”。

比如我们有两个文件,如下。


flocka.php

 代码如下 复制代码

$file = 'temp.txt';
    $fp = fopen($file,'a');
 
    for($i = 0;$i     {
        fwrite($fp, "11111111n");
        sleep(1);
    }
 
    fclose($fp);

flockb.php

 代码如下 复制代码
$file = 'temp.txt';
    $fp = fopen($file,'a');
 
    for($i = 0;$i     {
        fwrite($fp, "22222222n");
    }
 
    fclose($fp);

先运行flocka.php,然后马上运行flockb.php。
结果:
11111111
22222222
22222222
22222222
22222222
22222222
11111111
11111111
11111111
11111111
说明不加文件锁时,两个文件会同时对txt文件进行写入操作。
下面修改一下两个php文件的代码。
flocka.php

 代码如下 复制代码
$file = 'temp.txt';
    $fp = fopen($file,'a');
 
    if(flock($fp,LOCK_EX))
    {
        for($i = 0;$i         {
            fwrite($fp, "11111111n");
            sleep(1);
        }
        flock($fp,LOCK_UN);
    }
    fclose($fp);

flockb.php

 代码如下 复制代码
$file = 'temp.txt';
    $fp = fopen($file,'a');
 
    if(flock($fp,LOCK_EX))
    {
        for($i = 0;$i         {
            fwrite($fp, "22222222n");
        }
         flock($fp,LOCK_UN);
    }
 
    fclose($fp);

同样先运行flocka.php,然后马上运行flockb.php。
会发现在flocka.php运行结束前,flockb.php一直处于等待状态,只有当flocka.php运行结束后,flockb.php才会继续执行。
输出结果:
11111111
11111111
11111111
11111111
11111111
22222222
22222222
22222222
22222222
22222222
另外,在执行flock时,文件锁会自动释放。


还有一种办法


如下代码简单模拟了这种事务并发状态: process1.php

 代码如下 复制代码
      $num = 100;
    $filename = "processdata.txt";
 
    $fp = fopen($filename, "a");
    for ($i = 0; $i         fwrite($fp, "process1: " . $i . "rn");
        usleep(100000);
    }
    fclose($fp);
    ?>

我们需要先执行第一个事务,在processdata.txt文件中写入这100行。

process2.php

 代码如下 复制代码

      $num = 100;
    $filename = "processdata.txt";
 
    $fp = fopen($filename, "a");
    for ($i = 0; $i         fwrite($fp, "process2: " . $i . "rn");
        usleep(100000);
    }
    fclose($fp);
    ?>

第二个事务,继续向processdata.txt文件中写入100行。

第二个事务,继续向processdata.txt文件中写入100行。

多次同时执行,虽然都写了100行,但是事务1和事务2的数据交错写入,这并不是我们想要的结果。我们要的是事务完整的执行,此时我们需要有个机制去保证在第一个事务执行完后再执行第二个。在PHP中,flock函数完成了这一使命。在事物1和事务2的循环前面都加上: flock($fp, LOCK_EX); 就能满足我们的需求,将两个事务串行。

当某一个事务执行完flock时,因为我们在这里添加的是LOCK_EX(独占锁定),所以所有对资源的操作都会被阻塞,只有当事务执行完成后,后面的事务才会执行。我们可以通过输出当前的时间的方法来确认这一点。

关于在尾部追加写入,在unix系统的早期版本中存在一个并发写入的问题,如果要在尾部追加,需要先lseek位置,再write。当多个进程同时操作时,会因为并发导致的覆盖写入的问题,即两个进程同时获取尾部的偏移后,先后执行write操作,后面的操作会将前面的操作覆盖。这个问题在后面以添加打开时的O_APPEND操作而得到解决,它将查找和写入操作变成了一个原子操作。

在PHP的fopen函数的实现中,如果我们使用a参数在文件的尾部追加内容,其调用open函数中oflag参数为 O_CREAT|O_APPEND,即我们使用追加操作不用担心并发追加写入的问题。

在PHP的session默认存储实现中也用到了flock文件锁,当session开始时就调用PS_READ_FUNC,且以O_CREAT | O_RDWR | O_BINARY 打开session数据文件,此时会调用flock加上写锁,如果此时有其它进程访问此文件(即同一用户再次发起对当前文件的请求),就会显示页面加载中,进程被阻塞了。加写锁其出发点是为了保证此次会话中对session的操作事务能完整的执行,防止其它进程的干扰,保证数据的一致性。如果一个页面没有session修改操作,可以尽早的调用session_write_close()释放锁。

文件锁是针对文件的锁,除了这种释义,还可以理解为用文件作为锁。在实际工作中,有时为确保单个进程的执行,我们会在程序执行前判断文件是否存在,如果不存在则创建一个空文件,在进程结束后删除这个空文件,如果存在,则不执行。

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

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。