提问人:HelloMachine 提问时间:3/28/2022 更新时间:9/7/2022 访问量:810
PHP纤维等到完成,我不想等待
PHP fiber waits until finish which i don't want to wait
问:
我想使用 (PHP 8.1) 创建一个线程来发送电子邮件(电子邮件发送需要 10 秒,所以我决定使用线程)。这是我的代码Fiber
<?php
$fiber = new Fiber(function () {
send_email();
});
$fiber->start();
exit(json_encode(['response' => 1]));
结果并不重要,但在启动光纤后,光纤会等到完成然后发生!!!我希望它立即退出,但发送电子邮件太!!
问题是什么?send_email()
send_email()
exit(json_encode(['response' => 1]));
答:
根据 https://www.php.net/manual/en/language.fibers.php Fiber 是可中断的,但没有提到它是完全异步或多线程的——它不允许 main 函数继续自动执行......根据我对它的阅读,这只有在您暂停 Fiber 时才会发生 - 事实上,这就是您在代码中报告的体验。
PHP 是单线程的,也没有任何适当的基于任务的异步编程模型(不幸的是,与其他服务器端语言(如 nodeJS 或 C#)相比,这现在是一个主要弱点)。
https://php.watch/versions/8.1/fibers 还说
重要的是,并发执行并不意味着同时执行 执行。光纤和主执行流不会发生在 同一时间。由主执行流程来启动光纤, 当它开始时,Fiber 是专门执行的。
和
光纤本身不允许同时执行多个光纤或主线和光纤。
...所以我认为也许您误解了此功能及其功能 - 它无法帮助您满足您的要求。
AFAIK与PHP一起,不可能做你正在尝试的事情。更好的解决方案可能是将电子邮件发送移交给单独的进程 - 例如,由 触发的后台任务。这是一个相当典型的模式:PHP 收到一个请求,要求它发送电子邮件。它将请求记录在数据库表中,然后退出。后台任务按计划执行,从数据库表中选取任何未完成的任务并运行它们,然后更新表以表明它们已完成。这样一来,后台任务是否需要更长的时间并不重要,因为它不会减慢网站或最终用户的速度。cron
评论