当前位置: 首页 > 后端技术 > PHP

每个PHP程序员都应该知道的进程知识

时间:2023-03-29 22:13:53 PHP

作为工作多年的老程序员,你对进程和线程的理解是否还很匮乏?您在工作中使用流程管理吗?你知道进程间通信有几种方式吗?本文将介绍以下几个问题:①进程和线程介绍②进程间通信方式③Swoole中进程管理介绍1.进程和线程实例介绍。当程序运行时,系统会创建一个进程,为它分配资源,然后把这个进程放入进程的就绪队列中,这样当进程调度器选中它的时候,就会为它分配一个CPU时间片。进程的状态有:新建状态、就绪状态、运行状态、阻塞状??态、退出状态。状态可以转换:ready->running,running->ready,running->blocking,blocking->ready①newstatenew状态进程第一次创建时的状态。创建进程时,进程首先申请一块空白的进程控制块(PCB),并在PCB中填写控制和管理进程的信息;然后将运行所需的资源分配给这个进程;最后将进程转移到就绪状态并插入就绪队列。②就绪状态就绪状态是指有一个进程在等待执行,它有执行资格,但没有执行权限。执行资格是指除CPU以外的所有必要资源都已经分配完毕,没有执行权限是因为没有获得CPU。③运行态运行态进程是指进程已经获得了CPU,同时具备执行资格和执行权,处于运行状态。在单处理器(CPU)系统中,一次只能运行一个进程。在多处理器系统中,多个进程可以同时运行。④阻塞状态阻塞状态是指进程在执行过程中遇到阻塞,暂时无法继续运行,就会转为阻塞状态。进程阻塞的原因是I/O请求,时间片用完,遇到一些错误等等。⑤退出状态表示进程停止运行。进程进入退出状态的原因包括:程序执行完成、调用退出函数、遇到错误、收到终止信号、进程被操作系统杀死等。当进程退出时,操作系统会清除进程的PCB并将PCB空间归还给系统。一个进入终止状态的进程不能再次执行,但在操作系统中仍然保存着一条记录,它保存了状态码和一些时间统计信息,供其他进程收集。一旦其他进程提取完它的信息,操作系统就会删除它的进程,也就是清除它的PCB,并将空白的PCB返回给系统。说完进程,再来说说线程。线程是CPU调度的最小单位,线程也是一种有限的系统资源。一个进程可以由多个线程组成,进程的所有资源在线程之间共享,每个线程都有自己的栈和局部变量。线程由CPU独立调度执行,允许多个线程在多CPU环境下同时运行。同样,多线程也可以实现并发操作,每个请求分配一个线程去处理。线程的状态类似于进程的状态。一个进程可以运行多个线程,多个线程可以共享数据。只是之前线程切换消耗的CPU资源比进程切换要小。与进程不同的是,多个同类线程共享进程的堆和方法区资源,但每个线程都有自己的程序计数器、虚拟机栈和本地方法栈,所以系统生成一个线程,或者各个线程之间线程在作业之间切换时,负担比进程小很多,正因如此,线程也被称为轻量级进程。进程和线程有什么区别?本质区别:进程是操作系统资源分配的基本单位,而线程是CPU任务调度和执行的基本单位。空间与资源:进程相互独立,统一进程中的线程可以共享资源。不同进程中的线程相互独立。切换开销:进程有自己独立的代码段和数据空间(程序上下文),进程之间的切换需要保存上下文、寄存器等数据,会有较大的开销;同一个进程中的线程共享代码段和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程间切换的开销很小。相互关系:一个进程崩溃后,不会影响保护模式下的其他进程,但是如果一个线程崩溃了,整个进程就会挂掉。执行顺序:一个进程有自己的程序入口、顺序执行顺序和程序出口。但是线程不能独立执行,必须依赖于应用程序。应用程序提供多线程执行控制,两者可以并发执行。2.进程间通信方式简介在进程间通信之前,我们先介绍一个概念:用户态和内核态。当一个进程正在执行自己的代码时,它就处于用户态,而当进程因为系统调用而陷入内核代码时,它就处于内核态。执行的内核代码会使用当前进程的内核栈,每个进程都有自己的内核栈。当用户运行程序时,程序创建的进程开始运行自己的代码,并处于用户态。如果要进行文件操作、网络数据传输等操作,就必须通过write、send等系统调用,而这些系统调用会调用内核的代码。进程会进入内核地址空间执行内核代码完成相应的操作,处于内核态的进程执行完后会回到用户态。这样,用户态的程序就不能随意操作内核地址空间,起到了一定的安全保护作用,保证了进程之间的地址空间不会相互冲突,一个进程的操作不会修改另一个进程的地址空间中的数据。进程从用户态切换到内核态的常见方式有3种:系统调用(如fork调用)、异常(如缺页异常)、外围设备中断。先说进程间通信,也就是IPC,全称InterProcessCommunication。不同的进程可以相互通信并交换数据。进程间的通信方式包括:管道(包括无名管道和有名管道)、消息队列、信号量、共享内存、Sockets和Streams。①管道:管道分为无名管道和有名管道。无名管道是单向的,只允许单向通信。如果需要双向通信,需要开通两条单向管道。命名管道是存在于文件系统目录中的管道文件。管道文件只是文件系统中的标记,不占用磁盘空间。使用时,在内存上开辟空间,作为两个进程数据交互的通道。②消息队列:消息队列以消息链表的形式存储在内核中,由消息队列标识符标识。消息队列克服了信号传输信息少,管道只能承载无格式字节流,缓冲区大小有限等缺点。③信号量:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它通常用作锁定机制,以防止其他进程在一个进程正在访问共享资源时访问共享资源。因此,它主要用作进程之间以及同一进程中不同线程之间的同步手段。④共享内存:共享内存是映射一段内存,可以被其他进程访问。此共享内存由一个进程创建,但多个进程可以访问它。共享内存是最快的IPC方法,它专门设计用于在运行其他进程间通信方法的地方运行效率低下。它常与信号量等其他通信机制结合使用,以实现进程间的同步和通信。⑤SocketSocket也是一种进程间通信机制。与其他通信机制不同,它可以用于不同进程之间的进程通信。3.Swoole中的进程管理介绍接下来我们通过Swoole中的Process模块??来加深对进程的理解。在Swoole中,子进程是通过swoole_process类创建的。构造函数原型如下:$function为回调函数,在子进程创建成功后执行。$redirect_stdin_stdout参数可以重定向子进程的标准输入输出。$pipe_type为管道类型,具体参数含义请参考Swoole官方文档。接下来,我们将在一个进程中创建一个子进程,并在进程之间进行通信。在命令行执行phpprocess.php,运行后结果如下:这是一个进程间通过管道通信,创建子进程,设置回调函数的例子。Event::add将管道文件描述符$process->pipe添加到事件循环中。第一行输出的helloworld是回调函数输出的,read:aaaaaa是执行事件循环时从管道中读取的数据。Swoole中还有其他进程间通信的方式,这里不再一一列举。以上内容如有错误,敬请指正!