我想同时处理多个进程。我搜索并发现使用 ReactPHP 可以发生这种情况。我尝试过但没有成功。我添加了每个进程开始/结束时间的时间,结果显示每个函数的开始时间不相同。我希望每个函数的开始时间应该相同。
这是我的代码
<?php
require 'vendor/autoload.php';
use React\EventLoop\Factory;
use React\Promise\Promise;
$loop = Factory::create();
function asyncTask($taskName)
{
return new Promise(function ($resolve) use ($taskName) {
$startTime = (int)microtime(true);
echo "Starting $taskName at " . date('Y-m-d H:i:s', $startTime) . "\n";
$loop = React\EventLoop\Factory::create();
$loop->addTimer(rand(1, 5), function () use ($resolve, $taskName, $startTime) {
$endTime = (int)microtime(true);
echo "Completed $taskName at " . date('Y-m-d H:i:s', $endTime) . "\n";
$resolve([
'taskName' => $taskName,
'startTime' => $startTime,
'endTime' => $endTime,
]);
});
$loop->run();
});
}
$promises = [
'Task 1' => asyncTask('Task 1'),
'Task 2' => asyncTask('Task 2'),
'Task 3' => asyncTask('Task 3'),
];
\React\Promise\all($promises)->then(function ($results) {
echo "All tasks completed: <br>";
foreach ($results as $result) {
echo "{$result['taskName']} started at " . date('Y-m-d H:i:s', $result['startTime']) . " and ended at " . date('Y-m-d H:i:s', $result['endTime']) . "\n";
}
});
$loop->run();
?>
结果如下所示
于2024-01-18 17:37:09开始任务1
已于 2024-01-18 17:37:10 完成任务 1
2024-01-18 17:37:10开始任务2
已于 2024-01-18 17:37:14 完成任务 2
于2024-01-18 17:37:14开始任务3
已于 2024-01-18 17:37:15 完成任务 3
所有任务已完成:
任务1于2024-01-18 17:37:09开始并于2024-01-18 17:37:10结束
任务2于2024-01-18 17:37:10开始并于2024-01-18 17:37:14结束
任务3于2024-01-18 17:37:14开始并于2024-01-18 17:37:15结束
我想看到每个任务的开始时间为2024-01-18 17:37:09
ReactPHP 核心开发人员在这里。有几件事,首先我们改变了事件循环的使用方式,这样你只需要在你的情况下调用
Loop::addTimer
。其次,您将在文件顶部创建一个新的事件循环,然后在每个函数调用中创建一次,总共 4 次。正如 Sammitch 所指出的,您仍然在一个线程中完成所有这些操作。因此,除非您想开始使用 ext-parallel 或 React/child-process,否则您仍将在同一个单核进程中完成所有操作。除非您正在执行 CPU 密集型操作,否则单个进程不会成为问题。如果您正在进行 CPU 密集型操作,子进程可以帮助您。
使用我们的异步包,您可以编写以下代码:
<?php
use React\EventLoop\Loop;
use React\Promise\Promise;
use function React\Async\async;
use function React\Async\await;
use function React\Promise\all;
use function React\Promise\Timer\sleep;
use function random_int;
require 'vendor/autoload.php';
/**
* @return array<string, float>
*/
function asyncTask($taskName): array
{
$startTime = (int)microtime(true);
echo "Starting $taskName at " . date('Y-m-d H:i:s', $startTime) . "\n";
await(sleep(random_int(1, 5)));
$endTime = (int)microtime(true);
echo "Completed $taskName at " . date('Y-m-d H:i:s', $endTime) . "\n";
return [
'taskName' => $taskName,
'startTime' => $startTime,
'endTime' => $endTime,
];
}
$promises = [
'Task 1' => async(asyncTask('Task 1'))(),
'Task 2' => async(asyncTask('Task 2'))(),
'Task 3' => async(asyncTask('Task 3'))(),
];
results = await(all($promises));
echo "All tasks completed: <br>";
foreach ($results as $result) {
echo "{$result['taskName']} started at " . date('Y-m-d H:i:s', $result['startTime']) . " and ended at " . date('Y-m-d H:i:s', $result['endTime']) . "\n";
}