如何在PHP中使用ReactPHP获取并发

问题描述 投票:0回答:1

我想同时处理多个进程。我搜索并发现使用 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

php asynchronous reactphp concurrently
1个回答
1
投票

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";
}
© www.soinside.com 2019 - 2024. All rights reserved.