php - 多线程 PHP
问题描述
我在PHP中遇到了多线程的问题,我想在调用函数FunctionAync时,它返回后,它仍然处理函数Process(目前它只在完成处理函数Process后才返回),我该怎么办?
<?php
namespace App\Http\Controllers\Helper;
use Illuminate\Http\Request;
use Spatie\Async\Pool;
class AsyncTask
{
function functionAsync(Request $request){
$pool = Pool::create();
$pool->add(function () use ($request){
$this->Process($request);
})->then(function ($output) {
return;
})->catch(function (Throwable $exception) {
return;
});
await($pool);
return;
}
function Process($request){
sleep(1000);
}
}
解决方案
多线程在 php 中是可能的
是的,您可以使用pthreads在 PHP 中执行多线程
从PHP 文档:
pthreads 是一个面向对象的 API,它提供了 PHP 中多线程所需的所有工具。PHP 应用程序可以创建、读取、写入、执行和与线程、Worker 和线程对象同步。
警告:pthreads 扩展不能在 Web 服务器环境中使用。因此,PHP 中的线程应该只保留给基于 CLI 的应用程序。
简单测试
#!/usr/bin/php
<?php
class AsyncOperation extends Thread {
public function __construct($arg) {
$this->arg = $arg;
}
public function run() {
if ($this->arg) {
$sleep = mt_rand(1, 10);
printf('%s: %s -start -sleeps %d' . "\n", date("g:i:sa"), $this->arg, $sleep);
sleep($sleep);
printf('%s: %s -finish' . "\n", date("g:i:sa"), $this->arg);
}
}
}
// Create a array
$stack = array();
//Initiate Multiple Thread
foreach ( range("A", "D") as $i ) {
$stack[] = new AsyncOperation($i);
}
// Start The Threads
foreach ( $stack as $t ) {
$t->start();
}
?>
第一次运行
12:00:06pm: A -start -sleeps 5
12:00:06pm: B -start -sleeps 3
12:00:06pm: C -start -sleeps 10
12:00:06pm: D -start -sleeps 2
12:00:08pm: D -finish
12:00:09pm: B -finish
12:00:11pm: A -finish
12:00:16pm: C -finish
第二轮
12:01:36pm: A -start -sleeps 6
12:01:36pm: B -start -sleeps 1
12:01:36pm: C -start -sleeps 2
12:01:36pm: D -start -sleeps 1
12:01:37pm: B -finish
12:01:37pm: D -finish
12:01:38pm: C -finish
12:01:42pm: A -finish
现实世界的例子
error_reporting(E_ALL);
class AsyncWebRequest extends Thread {
public $url;
public $data;
public function __construct($url) {
$this->url = $url;
}
public function run() {
if (($url = $this->url)) {
/*
* If a large amount of data is being requested, you might want to
* fsockopen and read using usleep in between reads
*/
$this->data = file_get_contents($url);
} else
printf("Thread #%lu was not provided a URL\n", $this->getThreadId());
}
}
$t = microtime(true);
$g = new AsyncWebRequest(sprintf("http://www.google.com/?q=%s", rand() * 10));
/* starting synchronization */
if ($g->start()) {
printf("Request took %f seconds to start ", microtime(true) - $t);
while ( $g->isRunning() ) {
echo ".";
usleep(100);
}
if ($g->join()) {
printf(" and %f seconds to finish receiving %d bytes\n", microtime(true) - $t, strlen($g->data));
} else
printf(" and %f seconds to finish, request failed\n", microtime(true) - $t);
}
推荐阅读
- c# - 如何将数据从一个数组复制到另一个数组而不覆盖
- cordova - 归档 Cordova 应用程序期间找不到标头(未找到“WebRTC/RTCAudioSource.h”)
- regex - AWK 多次更改字段分隔符
- javascript - Webpack 5 收到 Polyfill 错误?!?!我的 JavaScript React 项目在尝试编译我的 webpack.config.js 文件时收到一个 polyfill 错误
- firebase - 文档中的用户功能不起作用 Flutter
- python - 我如何在python中每分钟重做一些事情
- python - 根据列名反转数据框的列
- python - 如何在 models.py 中获取当前用户?
- javascript - Vue JS - 循环组件
- kubernetes - Kubernetes pod HPA 在维护/升级工作节点期间不工作