简体   繁体   English

PHP 光纤等待完成,我不想等待

[英]PHP fiber waits until finish which i don't want to wait

I want to create a thread using Fiber (PHP 8.1) to send an email (email sending takes 10 seconds, so I decide to use a thread for it).我想使用Fiber (PHP 8.1)创建一个线程来发送 email(电子邮件发送需要 10 秒,所以我决定使用一个线程)。 And this is my code这是我的代码

<?php
$fiber = new Fiber(function () {
    send_email();
});
$fiber->start();

exit(json_encode(['response' => 1]));

The result of send_email() is not important but after start the fiber, fiber waits until send_email() done then exit(json_encode(['response' => 1])); send_email()的结果并不重要,但是在启动光纤后,光纤会等到send_email()完成然后exit(json_encode(['response' => 1])); happen,?!!发生,?!! I want it to exit immediately, but send email too !!!我希望它立即退出,但也要发送 email !!! what is the problem?问题是什么?

According to https://www.php.net/manual/en/language.fibers.php the Fiber is interruptible, but there's no mention of it being full async or multithreading - it doesn't allow the main function to continue executing automatically...from my reading of it that would only occur if you paused the Fiber - and indeed that's the experience you've reported in your code. According to https://www.php.net/manual/en/language.fibers.php the Fiber is interruptible, but there's no mention of it being full async or multithreading - it doesn't allow the main function to continue executing automatically ...从我的阅读来看,只有在您暂停 Fiber 时才会发生这种情况 - 事实上,这就是您在代码中报告的体验。

PHP is single-threaded and also doesn't have any kind of proper task-based asynchronous programming model (unfortunately, that's now a major weakness compared to other server-side languages like nodeJS or C#). PHP 是单线程的,也没有任何适当的基于任务的异步编程 model(不幸的是,与其他服务器端语言如 nodeJS 或 C# 相比,这现在是一个主要弱点)。

https://php.watch/versions/8.1/fibers also says https://php.watch/versions/8.1/fibers还说

It is important the concurrent execution does not mean simultaneous execution.重要的是并发执行并不意味着同时执行。 The Fiber and the main execution flow does not happen at the same time. Fiber 和主执行流程不会同时发生。 It is up to the main execution flow to start a Fiber, and when it starts, the Fiber is executed exclusively.启动一个 Fiber 由主执行流程决定,当它启动时,该 Fiber 被排他地执行。

and

Fiber by itself does not allow simultaneous execution of multiple Fibers or the main thread and a Fiber. Fiber 本身不允许同时执行多个 Fiber 或主线程和一个 Fiber。

...so I think perhaps you've misunderstood this feature and what it's capable of - it cannot help you to meet your requirement. ...所以我认为您可能误解了此功能及其功能 - 它无法帮助您满足您的要求。

AFAIK with PHP it's not possible to do what you're attempting. AFAIK 与 PHP 不可能做你正在尝试的事情。 A better solution might be to hand off the email sending to a separate process - eg a background task triggered by cron .更好的解决方案可能是将 email 发送到单独的进程 - 例如由cron触发的后台任务。 This is a fairly typical pattern: the PHP receives a request which requires it to send an email.这是一个相当典型的模式:PHP 收到一个要求它发送 email 的请求。 It logs the request in a database table and then exits.它将请求记录在数据库表中,然后退出。 The background task executes on a schedule, picks up any uncompleted tasks from the database table and runs them, then updates the table to say they're completed.后台任务按计划执行,从数据库表中提取任何未完成的任务并运行它们,然后更新表以说明它们已完成。 That way it doesn't really matter much if the background task takes a bit longer, because it's not slowing down the website or the end users.这样,后台任务是否需要更长的时间并不重要,因为它不会减慢网站或最终用户的速度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM