## 进程是什么? > Linux进程是一个其中运行着一个或多个线程的地址空间和这些线程所需要的系统资源,Linux系统会在进程之间共享程序代码和系统函数库。 Linux 系统中进程存在父子关系,父进程拥有多个子进程,子进程只能有一个父进程。pid为0的进程为调度进程,也是根进程。系统中所有的进程构成了一个以调度进程为根的进程树。 ## 进程的状态 * D(不可中断休眠状态)——进程正在休眠并且不能恢复,直到一个事件发生为止。 * R(运行状态)——进程正在运行。 * S(休眠状态)——进程没有在运行,而在等待一个事件或是信号。 * T(停止状态)——进程被信号停止,比如,信号 SIGINT 或 SIGSTOP。 * Z(僵死状态)——标记为 的进程是僵死的进程,它们之所以残留是因为它们的父进程适当地销毁它们。如果父进程退出,这些进程将被 init 进程销毁。 ## 父进程与子进程 当父进程通过fork创建子进程,会复制父进程中的数据区、BSS区、堆栈、命令行参数以及环境变量表到子进程中,只有代码区是共享的。 为了创建子进程能更加的轻量,fork创建子进程时,不会进行复制的动作,子进程和父进程共享内存区,只有当子进程对数据进行写操作时,才会从父进程的内存区中复制到子进程的内存区,并进行写操作,复制以内存页为单位进行复制。这样就达到了延迟复制加载,减少了系统开销。 ## PHP 进程函数 > PHP语言中实现进程相关操作的是以`pcntl_*`为前缀的函数族(pcntl应该是process control的简称)。 一般说来多个进程可以加速任务完成速度,但是CPU在同一个时刻只能执行一个进程,操作系统通过调度算法在多个进程之间快速轮转CPU占用时间,弄的同一个CPU核心看起来好像同一时间真的可以支持多个进程似的然而实际上却并不是都是假象PS唬人的幻觉;其次是多个进程之间的数据是隔离的,子进程会继承走父进程的数据空间、堆、栈等信息,总之就是父子之间的正文段是共享的,但是存储空间是隔离的。 ## pcntl_fork() 函数创建了一个子进程 在当前进程当前位置产生分支(子进程) >[warning] 译注:fork是创建了一个子进程,父进程和子进程 都从fork的位置开始向下继续执行,不同的是父进程执行过程中,得到的fork返回值为子进程 号,而子进程得到的是0。 ``` echo 'master process id = ' . posix_getpid() . PHP_EOL; // 创建一个子进程 $pid = pcntl_fork(); //父进程和子进程都会执行下面代码 if ($pid == -1) { //错误处理:创建子进程失败时返回-1 die('could not fork'); } else if ($pid) { //父进程会得到子进程号(就是fork出来的),所以这里是父进程执行的逻辑 echo 'parent process id = ' . posix_getpid() . PHP_EOL; } else { //子进程得到的$pid为0, 所以这里是子进程执行的逻辑。 echo 'child process id = ' . posix_getpid() . PHP_EOL; } ``` > 执行顺序:1、先执行主进程。2、执行子进程。3、等待子进程退出 执行结果 ```bash # php pcntl_fork.php master process id = 20 parent process id = 20 child process id = 21 ```