画江湖之 PHP 多线程开发 [线程安全 互斥锁]

基本概念

线程同步的一种方式,保证共享数据操作的完整性。每个对象都对应于一个可称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象

同步控制方法 使用的函数

Threaded::synchronized()    在发起调用的线程上下文中获取对象同步锁,
                        然后同步执行代码块

Threaded::wait()            让发起调用的线程上下文进入等待,
                        直到收到其它线程的唤醒通知(notify)

Threaded::notify()          给对象发送唤醒通知

代码段

<?php

// 继承 Thread 的类具有创建线程的能力
class Request extends Thread
{
    private $file;

    public function __construct($file)
    {
        $this->file = $file;
    }

    public function run()
    {
        //发起一个上下文 获取同步锁
        $this->synchronized(function ($thread) {
            if (! $thread->done) {
                $thread->wait();//一个阻塞等待
            }
            //执行业务逻辑
            $c = file_get_contents($this->file);
            echo "before c = {$c}\n";
            $c = $c + 1;
            echo "after c = {$c}\n";
            file_put_contents($this->file, $c);
        }, $this);
    }
}

$file = '/tmp/data.txt';
$arr = [];
for ($i = 0; $i < 2000; $i++) {//2000个并发访问
    $request = new Request($file);
    $arr[$i] = $request;
    // 创建新线程,随后线程会执行 run 方法
    if (! $request->start()) {
        die("Start thread failed\n");
    }
//创建好一个线程 
    $request->synchronized(function ($thread) {
        $thread->done = true;
        $thread->notify();//唤醒通知 然后让别的线程获取到锁
    }, $request);
}

for ($i = 0; $i < 2000; $i++) {
    // join 是阻塞的,所以脚本运行时间取决于耗时最长的线程
    if (! $arr[$i]->join()) {
        die("Join failed\n");
    }
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!