我有一个PHP脚本,向用户显示Web表单。当用户提交表单时,我将数据保存在数据库中,然后我分叉一个进程,儿子,向一些用新的更改感染的数据库用户发送一些短信。
当我叉,我检查儿子,他正确发送短信,最后退出。 但由于某种原因,父亲等待儿子完成他的任务。我不知道为什么会发生这种情况..
以下是我的代码示例:
// before this point, i've inserted some data in the database, and now i commit the transaction
$conn->commit();
$pid = pcntl_fork();
if ($pid == 0) { // its the son, so he will send the messages
$conn = new PDO('oci:dbname='.SERVER.';charset='.CHARSET, DATABASE, PASSWORD);
$suppliersPhoneNumber = getSuppliersPhoneNumber($conn, ...);
$conn = null;
$sms = new MessageSender($suppliersPhoneNumber, $_POST['subCategory']);
$sms->handleMessages(); // send the sms
//sleep(60);
exit(0); // the son won't execute more code
}/
代码为“sleep(60)”的行是我知道父亲在等孩子的方式。但如果儿子退出,这怎么可能?我知道父亲在等儿子,因为事实上我的剧本冻结了1分钟,等待时间。
我的想法是让父亲在数据库中插入所需的数据,最后他产生了一个新的孩子来发送消息,但是没有等待他,所以我们可以向用户发送一个响应页面说一切都很顺利,而消息有效发送。
这里出了什么问题?
事先提出
修改 问题没有解决,而是我遵循下面注册的Paulo H.确实这是一种更好的方式。
答案 0 :(得分:1)
我相信您正在使用Apache运行此代码,我建议您完全运行separate process in the background。
我认为问题正在发生,因为Apache在将信息发送到浏览器之前等待这个子进程。无论如何不推荐使用fork,如果不是在php-cli脚本中。
通常子进程会保持僵尸模式,直到父进程调用“wait”,但似乎没有这种情况。
答案 1 :(得分:0)
通过分配进程,子进程将位于同一进程组中。也许Apache或您使用的任何Web服务器都在等待分组中的所有进程在分离和结束请求之前结束。
在分叉之后尝试在子代中调用setsid(),这应该将它作为新组中的领导者。
答案 2 :(得分:0)
而不是
exit();
尝试使用此
posix_kill(getmypid(),9);
请告诉我这是否有效。