PHP多线程扩展-parallel(一)

本文介绍了PHP并行扩展parallel的基本使用,包括安装步骤、Runtime对象创建、run方法、线程隔离与channel通信。重点讲解了如何利用channel进行线程间通信,并强调了其与多进程和内存共享的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PHP多线程扩展-parallel(一)

php其实也是有多线程的,比较有名的就是pthread 扩展,但是当我打开官网想学习一下,结果。
在这里插入图片描述
既然官方都放弃他了,那就看看parallel吧,百度谷歌了一下,几乎没人发文章….官网的说明全英文而且非常的简陋,凭着我的4级英语水平以及翻译软件勉强明白了几个核心api的使用…

安装

值得一提的是parallel扩展支持windows,从这点看就比 pthread 好多了,在cli是可以使用的,就是不知道在fpm下是否可以使用(经过测试无法再用于fpm)。

我直接在windows上测试的,windows上安装比较简单:

1.下载php7.2+,必须线程安全版本

2.下载 parallel 扩展

3.php_parallel.dll放到ext目录,php.ini加上extension=parallel(当然扩展目录也可自定义)

4.pthreadVC2.dll(扩展包里的)拖到php.exe同级,该目录添加环境变量。

php -m 运行查看是否存在 parallel 扩展

运行

相比pthread确实是简陋了不少,文档更简单,靠着一些常识理解了几个核心api。

runtime

创建一个运行对象

$thread=new \parallel\Runtime('G:\study\php\parallel\a.php');

参数是引导文件路径, parallel 创建线程的时候跟主线程是不共享代码的,也就是意味着新线程里没法使用原来代码里的类,所以需要传入一个引导文件,这个引导文件一般是autoload之类的自动加载文件。

runtime::run

重头戏了,运行一个线程。参数是一个闭包。

<?php


$r1=new \parallel\Runtime('G:\study\php\parallel\a.php');
$r2=new \parallel\Runtime('G:\study\php\parallel\a.php');
$a=5;
$future1=$r1->run(function ()use ($a){//线程1
    sleep(1);
    echo "this is thread1 start\n\r";
    $a++;
    echo "thread1 a is $a\n\r";
    sleep(5);
    echo "this is thread1 end\n\r";
    return 1;
});

$future2=$r2->run(function ($p1){//线程2
    echo "this is thread2 start\n\r";
    sleep(5);
    echo "thread2 a is $p1\n\r";
    echo "this is thread2 end\n\r";
    return 2;
},[$a]);//外部变量也可以通过第二个参数传入线程

$future3=$r2->run(function (){//线程3
    echo "this is thread3 start\n\r";
    sleep(5);
    echo "this is thread3 end\n\r";
    return 3;
});
echo "主线程开始\n\r";
echo "future1的值是:".$future1->value()."\n\r";
echo "future2的值是:".$future2->value()."\n\r";
echo "future3的值是:".$future3->value()."\n\r";

在这里插入图片描述
几个要点

1.同一个运行对象运行线程是单线程按顺序执行的,不同的运行对象运行线程是并发的。

2.线程与线程之间不能共享内存,php本身也不支持(TSRM),线程通信只能使用channel(下文会讲)。
在这里插入图片描述

3.future是run的返回的对象,future->value()可以获取线程闭包里返回的值,也就意味着程序运行到此处时该线程必然已经结束,所以可以通过多个future->value()实现等待多个线程完成的功能

channel

线程通信只能使用 channel,使用方法与golang一样,参数为容量,send时channel已满时线程堵塞,recv时channel为空时线程堵塞。可以传闭包!

$r1=new \parallel\Runtime('G:\study\php\parallel\a.php');
$r2=new \parallel\Runtime('G:\study\php\parallel\a.php');
$c=new \parallel\Channel(2);

$r1->run(function ()use($c){

    while (1){
        echo "开始获取...\n\r";
        $a=$c->recv();
        if($a instanceof Closure){
            $a();
        }else{
            print_r($a);
            echo "\n\r";
        }
    }

});

$r2->run(function ()use($c){
    $c->send(function (){
        echo "我是闭包\n\r";
    });
    sleep(5);
    $c->send([1,2,3]);
});

在这里插入图片描述

以上是几个核心api,其他可查阅官网,有时间再深入学习一下。

评价
不能共享内存,代码,与其他语言多线程相比局限性非常大,如果不是有个chanel实际跟多进程也没多大区别。相对于多进程,线程控制因为有chanel要易用一点…

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值