pcntl_fork在PHP中如何工作? [英] How does pcntl_fork work in PHP?

查看:274
本文介绍了pcntl_fork在PHP中如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对PHP中的 pcntl_fork 感到困惑.

I'm confused about pcntl_fork in PHP.

我认为它具有多线程功能,但是它如何工作以及如何在脚本中使用它呢?

I think it does multi-threading, but how does it work and how would I use it in a script?

推荐答案

PCNTL无法创建线程.它仅分叉"当前的PHP进程.这是什么意思?调用pcntl_fork()时,当前进程分为两个进程.父进程的整个名称空间被复制到子进程中,并且两个进程并行执行,但只有一个区别:pcntl_fork()在父进程中返回子进程的PID,在子进程中0返回.

PCNTL can not make threads. It only "forks" current PHP process. What does it mean? When you call pcntl_fork(), current process is split into two processes. Whole namespace of parent process is copied into the child and both processes continue with execution in parallel with only one difference: pcntl_fork() returns child's PID in parent and 0 in child.

一些提示:

  • 默认情况下处于禁用状态.如果您设法启用它,则仅在CLI上执行它.永远不要在Web服务器上使用它!它将以不确定的方式运行.它还可以使整个机器停机.请禁用它,然后继续阅读.
  • 进程之间的通讯是可能的,但很可怕(通过 共享内存中的序列化对象).
  • 文件描述符(和数据库) 共享),这经常会引起问题. 分支后,您必须重新连接数据库,否则当所有分支过程中的第一个关闭连接时,都会出现诸如MySQL server has gone away之类的错误.
  • 父进程必须等待孩子完成,否则将离开僵尸 进程消耗了背后的系统资源.
  • It is disabled by default. If you manage to enable it, then do it for CLI only. Never ever use it with web server! It will behave in non-deterministic way. It can also bring whole machine down. Please, leave it disabled and read on.
  • Communication between processes is possible but horrible (via serialized object in shared memory).
  • File descriptors (and database connections) are shared, this causes problems very often. You have to reconnect your DB after forking or you will get errors like MySQL server has gone away from all forked processes when first of them closes the connection.
  • Parent process have to wait for children to finish or it will leave zombie processes consuming system resources behind.

以下示例来自文档:

<?php

$pid = pcntl_fork();
if ($pid == -1) {
     die('could not fork');
} else if ($pid) {
     // we are the parent
     pcntl_wait($status); //Protect against Zombie children
} else {
     // we are the child
}

但是请记住,PHP只是脚本语言.它不是为并行计算而设计的.您可以根据需要同时运行CRON,消息队列或使用较低级语言的程序来做得更好.

But remember, PHP is just scripting language. It's not designed for parallel computing. You could do better job with simultaneously running CRONs, message queues or program in lower-level language, depending on your needs.

叉式PHP程序很难阅读,理解和调试.维持该计划将是一场噩梦.

Forked PHP program is very hard to read, understand and debug. Maintaining that program will be a nightmare.

不要犯错,避免分叉.不用了您真正需要的是异步任务运行器.好消息,有 RabbitMQ 兔子

Don't make mistake and avoid forking. You don't need it. What you really need is asynchronous task runner. Good news, there is RabbitMQ and nice tutorial ;-) You can also try promising RabbitMQ library called Bunny

PS:使用消息队列而不是派生为您提供了另一项优势.您可以使用多台服务器处理队列,并随着流量的增长而水平扩展.

PS: Using message queues instead of forking gives you one more advantage. You can process the queue with multiple servers and scale horizontally as your traffic grows.

编辑2019-03-07

EDIT 2019-03-07

我在异步并发框架amphp中发挥了很多作用,我不得不在这里提及.如果确实需要在单个请求中运行异步非阻塞任务,那么我认为amphp是当今最好的解决方案.它使用php生成器($value = yield $promise)的概念来执行人类可读的代码,而无需像reactphp一样的诺言地狱.

I have played a lot with asynchronous concurrency framework amphp and I have to mention it here. If you really need to run async non-blocking tasks in single request, I consider amphp to be the best solution today. It uses concept of php generators ($value = yield $promise) to execute human-readable code without reactphp-like promise hell.

https://amphp.org/

这篇关于pcntl_fork在PHP中如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆