本文作者:DurkBlue

php 谈一谈加锁功能推荐

DurkBlue 01-31 47542
php 谈一谈加锁功能摘要:         在PHP中,加锁是一种非常重要的机制。当多个进程或线程对同一个资源进行读写时,加锁可...

        在PHP中,加锁是一种非常重要的机制。当多个进程或线程对同一个资源进行读写时,加锁可以保证数据的一致性和正确性。PHP中的加锁可以分为两种:文件锁和共享内存锁。

文件锁是使用文件系统提供的锁机制,来控制多进程或多线程对该文件的访问。PHP中提供了 flock 函数来实现文件锁的功能。下面的代码展示了如何使用 flock 函数来进行文件锁的控制。

        

/**
*
@Notes: 用户领取优惠券
* @AuthorDurkBlue
*
@Time: 2024/1/31 10:30
*
@param int $userId
*
@param int $voucherId
*
@return bool
*
@Interface doReceiverCoupon
*/
public static function doReceiverCoupon(int $userId, int $voucherId): bool{
   try {
       // 文件加锁,防止多线程并发下导致的优惠券可领取等数据错乱异常
       
$myFile = fopen('/flock.txt', 'r+');
       
if (flock($myFile, LOCK_EX)) {
           $couponObj = DurkCoupon::findOrEmpty($voucherId);
           
if($couponObj->isEmpty()) throw new Exception("未找到该优惠券");
           
// 有无设置过期时间
           
$nowTime = time();
           
$validate_time = 0;
           
if($couponObj->get_over_hour > 0){
               $addValidateSecond = $couponObj->get_over_hour * 3600;
               
$validate_time = $nowTime + $addValidateSecond;
           
}
           $insert_data = [
               'voucher_id'            => $voucherId,
               
'voucher_title'         => $couponObj->voucher_title,
               
'user_id'               => $userId,
               
'credit'                => $couponObj->credit,
               
'limit_money'           => $couponObj->limit_money,
               
'type'                  => $couponObj->type,
               
'limit_officer_list'    => $couponObj->limit_officer_list,
               
'validate_time'         => $validate_time,
               
'create_time'           => $nowTime
           ];
           
$userCouponObj = DurkUserCoupon::create($insert_data);
           
if(!empty($userCouponObj->id)){
               // 给优惠券加上领取张数,并判断是否达到完结状态

           
}

           // 在此处进行文件的读写操作
           
flock($myFile, LOCK_UN);
       
}


   } catch (\Exception $e) {
       self::$error = $e->getMessage();
       
return false;
   
}
}


    php 谈一谈加锁功能  第1张


    

    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

    php 谈一谈加锁功能  第2张


    flockb.php


    php 谈一谈加锁功能  第3张


    

        先运行flocka.php,然后马上运行flockb.php。

        结果:

        11111111

        22222222

        22222222

        22222222

        22222222

        22222222

        11111111

        11111111

        11111111

        11111111

        说明不加文件锁时,两个文件会同时对txt文件进行写入操作。

        下面修改一下两个php文件的代码。

        flocka.php


        php 谈一谈加锁功能  第4张


    flockb.php


    php 谈一谈加锁功能  第5张


    

        同样先运行flocka.php,然后马上运行flockb.php。

        会发现在flocka.php运行结束前,flockb.php一直处于等待状态,只有当flocka.php运行结束后,flockb.php才会继续执行。

        输出结果:

        11111111

        11111111

        11111111

        11111111

        11111111

        22222222

        22222222

        22222222

        22222222

        22222222

        另外,在执行flock时,文件锁会自动释放。


        php还提供了一个共享内存锁来对程序进行加锁功能,共享内存锁是通过操作系统提供的共享内存实现的。PHP中提供了 shmop 函数和 sem 函数来实现共享内存锁的功能。下面的代码展示了如何使用 sem 函数进行共享内存锁的控制。


    

$key = 1234;
$sem_id = sem_get($key);
if (sem_acquire($sem_id)) {
    // 在此处进行对共享内存的读写操作
    sem_release($sem_id);
} else {
    // 锁定共享内存失败
}
sem_remove($sem_id);

    

    上述代码首先创建了一个信号量,并使用 sem_acquire 函数进行加锁。在操作共享内存后,又使用 sem_release 函数释放了锁。这样可以确保在同一时刻只有一个进程或线程访问共享内存。

    


此篇文章由DurkBlue发布,感谢转载需要请注明来处
文章投稿或转载声明

来源:DurkBlue版权归原作者所有,转载请保留出处。本站文章发布于 01-31
温馨提示:文章内容系作者个人观点,不代表DurkBlue博客对其观点赞同或支持。

赞(0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

阅读
分享