大佬们有个异步跟多线程的问题,救救孩子

框架:thinkphp6
PHP版本:8
以下代码,我要怎么实现b不等待c的执行结果直接return给a啊
在宝塔里面用pcntl_fork好像没效果

public static function a(b){
 $a = '我是a,我需要b返回结果来告诉我它执行了,我在返回结果给ajax客户端';
php::b();
return $a;
}

public static function b(){
 $b = '我是b,我要返回return给a,并且不想等待c执行结束就返回';
php::c();
return $b;
}

public static function c(){
sleep(20);
$c = '我是c,我需要20秒才能结束';
return $c;
}
Jyunwaa
最佳答案

revolt库

composer require revolt/event-loop
<?php
declare(strict_types=1);

use Revolt\EventLoop;

require __DIR__ . '/vendor/autoload.php';

function a()
{
    $a = '我是a,我需要b返回结果来告诉我它执行了,我在返回结果给ajax客户端';
    echo $a, PHP_EOL;
    b();
    return $a;
}

function b()
{
    $b = '我是b,我要返回return给a,并且不想等待c执行结束就返回';
    echo $b, PHP_EOL;
    EventLoop::defer(function () {
        c();
    });
    EventLoop::run();
    return $b;
}

function c()
{
    sleep(20);
    $c = '我是c,我需要20秒才能结束';
    echo $c, PHP_EOL;
    return $c;
}

a();
readline();

// 我是a,我需要b返回结果来告诉我它执行了,我在返回结果给ajax客户端
// 我是b,我要返回return给a,并且不想等待c执行结束就返回
// 我是c,我需要20秒才能结束

Swoole扩展

<?php
declare(strict_types=1);

use function Swoole\Coroutine\run;


function a()
{
    $a = '我是a,我需要b返回结果来告诉我它执行了,我在返回结果给ajax客户端';
    echo $a, PHP_EOL;
    b();
    return $a;
}

function b()
{
    $b = '我是b,我要返回return给a,并且不想等待c执行结束就返回';
    echo $b, PHP_EOL;
    go(c(...));
    return $b;
}

function c()
{
    sleep(20);
    $c = '我是c,我需要20秒才能结束';
    echo $c, PHP_EOL;
    return $c;
}

run(function () {
    go(a(...));
});


// 我是a,我需要b返回结果来告诉我它执行了,我在返回结果给ajax客户端
// 我是b,我要返回return给a,并且不想等待c执行结束就返回
// 我是c,我需要20秒才能结束
6个月前 评论
讨论数量: 8
Jyunwaa

revolt库

composer require revolt/event-loop
<?php
declare(strict_types=1);

use Revolt\EventLoop;

require __DIR__ . '/vendor/autoload.php';

function a()
{
    $a = '我是a,我需要b返回结果来告诉我它执行了,我在返回结果给ajax客户端';
    echo $a, PHP_EOL;
    b();
    return $a;
}

function b()
{
    $b = '我是b,我要返回return给a,并且不想等待c执行结束就返回';
    echo $b, PHP_EOL;
    EventLoop::defer(function () {
        c();
    });
    EventLoop::run();
    return $b;
}

function c()
{
    sleep(20);
    $c = '我是c,我需要20秒才能结束';
    echo $c, PHP_EOL;
    return $c;
}

a();
readline();

// 我是a,我需要b返回结果来告诉我它执行了,我在返回结果给ajax客户端
// 我是b,我要返回return给a,并且不想等待c执行结束就返回
// 我是c,我需要20秒才能结束

Swoole扩展

<?php
declare(strict_types=1);

use function Swoole\Coroutine\run;


function a()
{
    $a = '我是a,我需要b返回结果来告诉我它执行了,我在返回结果给ajax客户端';
    echo $a, PHP_EOL;
    b();
    return $a;
}

function b()
{
    $b = '我是b,我要返回return给a,并且不想等待c执行结束就返回';
    echo $b, PHP_EOL;
    go(c(...));
    return $b;
}

function c()
{
    sleep(20);
    $c = '我是c,我需要20秒才能结束';
    echo $c, PHP_EOL;
    return $c;
}

run(function () {
    go(a(...));
});


// 我是a,我需要b返回结果来告诉我它执行了,我在返回结果给ajax客户端
// 我是b,我要返回return给a,并且不想等待c执行结束就返回
// 我是c,我需要20秒才能结束
6个月前 评论
Jyunwaa

revolt库

composer require revolt/event-loop
<?php
declare(strict_types=1);

use Revolt\EventLoop;

require __DIR__ . '/vendor/autoload.php';

function a()
{
    $a = '我是a,我需要b返回结果来告诉我它执行了,我在返回结果给ajax客户端';
    echo $a, PHP_EOL;
    b();
    return $a;
}

function b()
{
    $b = '我是b,我要返回return给a,并且不想等待c执行结束就返回';
    echo $b, PHP_EOL;
    EventLoop::defer(function () {
        c();
    });
    EventLoop::run();
    return $b;
}

function c()
{
    sleep(20);
    $c = '我是c,我需要20秒才能结束';
    echo $c, PHP_EOL;
    return $c;
}

a();
readline();

// 我是a,我需要b返回结果来告诉我它执行了,我在返回结果给ajax客户端
// 我是b,我要返回return给a,并且不想等待c执行结束就返回
// 我是c,我需要20秒才能结束

Swoole扩展

<?php
declare(strict_types=1);

use function Swoole\Coroutine\run;


function a()
{
    $a = '我是a,我需要b返回结果来告诉我它执行了,我在返回结果给ajax客户端';
    echo $a, PHP_EOL;
    b();
    return $a;
}

function b()
{
    $b = '我是b,我要返回return给a,并且不想等待c执行结束就返回';
    echo $b, PHP_EOL;
    go(c(...));
    return $b;
}

function c()
{
    sleep(20);
    $c = '我是c,我需要20秒才能结束';
    echo $c, PHP_EOL;
    return $c;
}

run(function () {
    go(a(...));
});


// 我是a,我需要b返回结果来告诉我它执行了,我在返回结果给ajax客户端
// 我是b,我要返回return给a,并且不想等待c执行结束就返回
// 我是c,我需要20秒才能结束
6个月前 评论

我赌你在 nginx 下,fpm 运行模式。 那么,最简单的方式就是 fastcgi_finish_request

public static function a(b){
 $a = '我是a,我需要b返回结果来告诉我它执行了,我在返回结果给ajax客户端';
php::b();
return $a;
}

public static function b(){
 $b = '我是b,我要返回return给a,并且不想等待c执行结束就返回';
php::c();
return $b;
}

public static function c(){

if (function_exists('fastcgi_finish_request')) {
    echo '先返回,别等我'fastcgi_finish_request();
    set_time_limit(0);  //避免超时报错
    ini_set('memory_limit', '-1');  //避免内存不足
    sleep(20);
    $c = '我是c,我需要20秒才能结束';
    return $c;
} else {
    // 用他们的方法吧
}

}
6个月前 评论
guling (楼主) 6个月前

虽然你用不了 pcntl_fork 但是我还是要贴个例子 :grin::

<?php

function a()
{
    b();
    echo '我是A,得到结果后立刻返回', PHP_EOL;
}

function b()
{
    // 创建子进程处理c
    $pid = pcntl_fork();
    if ($pid == 0) {
        c();
        exit();
    } else {
        pcntl_waitpid(0, $status, WNOHANG);

        echo '我是B,要把结果返回给A,但是不要等C结束', PHP_EOL;
    }
}
function c()
{
    sleep(20);
    echo '我是C,我延迟二十秒后执行', PHP_EOL;
    exit();
}

a();
6个月前 评论
guling (楼主) 6个月前
qufo 5个月前

收藏一下

5个月前 评论

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