进程-线程-协程

2024-08-22 21:38
文章标签 线程 进程 协程

本文主要是介绍进程-线程-协程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

进程是什么?

       计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配独立实体, 且每个进程拥有独立的地址空间,是操作系统结构的基础[最小的资源管理单元]

结论:进程是一个执行中的程序,需由上而下的一步步执行完成,既是基本的分配单元,也是基本的执行单元

线程是什么?

进程中的一个实体,只拥有运行时必不可少的资源,可与同一个进程下的所有线程共享资源[进程中的所有资源],别称:轻量级进程[程序执行流的最小单元|程序实际执行者]

结论:单个程序同时运行多个线程完成不同的工作,称为多线程

进程与线程的通俗理解:

示例1:

有一个老板想要开个工厂进行生产某件商品(例如剪子)

       他需要花一些财力物力制作一条生产线,这个生产线上有很多的器件以及材料这些所有的 为了能够生产剪子而准备的资源称之为:进程。


只有生产线是不能够进行生产的,所以老板的找个工人来进行生产,这个工人能够利用这些材料最终一步步的将剪子做出来,这个来做事情的工人称之为:线程。


这个老板为了提高生产率,想到3种办法:
(1)在这条生产线上多招些工人,一起来做剪子,这样效率是成倍増长,即单进程 多线程方式
(2)老板发现这条生产线上的工人不是越多越好,因为一条生产线的资源以及材料毕竟有限,所以老板又花了些财力物力购置了另外一条生产线,然后再招些工人这样效率又再一步提高了,即多进程 多线程方式
(3)老板发现,现在已经有了很多条生产线,并且每条生产线上已经有很多工人了(即程序是多进程的,每个进程中又有多个线程),为了再次提高效率,老板想了个损招,规定:如果某个员工在上班时临时没事或者再等待某些条件(比如等待另一个工人生产完谋道工序 之后他才能再次工作) ,那么这个员工就利用这个时间去做其它的事情,那么也就是说:如果一个线程等待某些条件,可以充分利用这个时间去做其它事情,其实这就是:协程方式。

示例2:

 ​​​​​​​

 进程:手机工厂车间[拥有资源]

线程:车间员工[实际执行人]

车间目的:生产成品[手机]

工厂车间中拥有着生产手机成品的所有资源。而车间员工都有着各自的工作岗位责任,负责某一块的业务,可以与人协助,生产出一部手机

图形理解:

代码示例:

多进程是依靠 pcntl_fork 来创建子进程,在启用多进程的时候需要进行模块检测

$processNumber = 5 ; #最大进程数if (function_exists('pcntl_fork')) {$pids = array();for ($x = 0; $x < $processNumber; $x++) {$pid = pcntl_fork();if ($pid == -1) {$this->log->writeLine("创建子进程失败!!\n");} elseif ($pid) {// 父进程. -- 一般不做任何处理echo '父进程最后执行'.PHP_EOL;$pids[] = $pid;} else {// 子进程.$this->run($this->processNumber);//  业务处理的地方echo '测试'.PHP_EOL;exit();}}// 等待子进程结束foreach ($pids as $pid) {pcntl_waitpid($pid, $status);}
} else {echo '当前PHP版本不支持pcntl_fork功能,运行失败'.PHP_EOL;exit();
}

PHP 本身是不支持多线程的,通过socket的方式来实现PHP多线程。

  • 协程是什么?

一种轻量级的线程,只拥有寄存器上下文和栈,对栈操作,没有内核切换的开销,可以不加锁访问全局变量。

结论:原生的协程依靠yield和Generator[生成器]来实现。因没有内核切换开销,在IO瓶颈的时候可以很好的解决性能问题,可由用户在代码中控制,不陷入系统的控制

代码示例:

$result = $this->createRange(10); // 这里调用上面我们创建的函数
foreach($result as $value){sleep(1);echo $value.'<br />';
}function createRange($number){for($i=0;$i<$number;$i++){$data[] = time();}return $data;
}function createRange($number){for($i=0;$i<$number;$i++){yeild time();}
}

进程间的通信(IPC):

  1. 可通过消息队列进行通信,比如rabbitMQ,Kafka,Posix消息队列等,通过生产者和消费中的关系,进行数据交互
  2. 信号量,系统的一种原子性操作,同时只有一个进程能操作,当进程获取到某个信号量的时候,该进程就应该被释放掉。  

        sem_acquire 获取信号量

        sem_release 释放信号量

  1. 共享内存,在系统中开辟一个公共的内存区域,任何进程同一时刻都可以访问该区域,为了确保数据一致性,需要对该区域进行加锁或者信号量
  2. 管道[posix_mkfifo],常用的进程间常用的通信手段,分为无名管道和有名管道,无名管道只能用于具有亲缘关系的进程间通信,而有名管道可以用于同一主机上任意进程

代码示例:

// 定义管道路径,与创建管道
$pipe_path = '/data/test.pipe';  
if(!file_exists($pipe_path)){if(!posix_mkfifo($pipe_path,0664)){exit("create pipe error!");}
}
$pid = pcntl_fork();
if($pid == 0){ // 子进程,向管道写数据$file = fopen($pipe_path,'w');while (true){fwrite($file,'hello world');$rand = rand(1,3); sleep($rand);}exit('child end!');
}else{ // 父进程,从管道读数据$file = fopen($pipe_path,'r');while (true){$rel = fread($file,20);echo "{$rel}\n";$rand = rand(1,2);sleep($rand);}
}

总结:

1、在web应用中,我们每次访问php,就建立一个PHP进程,当然也会建立至少一个PHP线程。

2、PHP使用pcntl来进行多进程编程

3、PHP中使用pthreads来进行多线程编程

4、nginx的每个进程只有一个线程,每个线程可以处理多个客户端的访问

5、php-fpm使用多进程模型,每个进程只有一个线程,每个线程只能处理一个客户端访问。

6、apache可能使用多进程模型,也可能使用多线程模型,取决于使用哪种SAPI.

7、进程是cpu资源分配的最小单位,线程是cpu调度的最小单位

这篇关于进程-线程-协程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1097471

相关文章

Spring Boot3虚拟线程的使用步骤详解

《SpringBoot3虚拟线程的使用步骤详解》虚拟线程是Java19中引入的一个新特性,旨在通过简化线程管理来提升应用程序的并发性能,:本文主要介绍SpringBoot3虚拟线程的使用步骤,... 目录问题根源分析解决方案验证验证实验实验1:未启用keep-alive实验2:启用keep-alive扩展建

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

Java终止正在运行的线程的三种方法

《Java终止正在运行的线程的三种方法》停止一个线程意味着在任务处理完任务之前停掉正在做的操作,也就是放弃当前的操作,停止一个线程可以用Thread.stop()方法,但最好不要用它,本文给大家介绍了... 目录前言1. 停止不了的线程2. 判断线程是否停止状态3. 能停止的线程–异常法4. 在沉睡中停止5

Linux中的进程间通信之匿名管道解读

《Linux中的进程间通信之匿名管道解读》:本文主要介绍Linux中的进程间通信之匿名管道解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、基本概念二、管道1、温故知新2、实现方式3、匿名管道(一)管道中的四种情况(二)管道的特性总结一、基本概念我们知道多

Linux进程终止的N种方式详解

《Linux进程终止的N种方式详解》进程终止是操作系统中,进程的一个重要阶段,他标志着进程生命周期的结束,下面小编为大家整理了一些常见的Linux进程终止方式,大家可以根据需求选择... 目录前言一、进程终止的概念二、进程终止的场景三、进程终止的实现3.1 程序退出码3.2 运行完毕结果正常3.3 运行完毕

Windows命令之tasklist命令用法详解(Windows查看进程)

《Windows命令之tasklist命令用法详解(Windows查看进程)》tasklist命令显示本地计算机或远程计算机上当前正在运行的进程列表,命令结合筛选器一起使用,可以按照我们的需求进行过滤... 目录命令帮助1、基本使用2、执行原理2.1、tasklist命令无法使用3、筛选器3.1、根据PID

Java捕获ThreadPoolExecutor内部线程异常的四种方法

《Java捕获ThreadPoolExecutor内部线程异常的四种方法》这篇文章主要为大家详细介绍了Java捕获ThreadPoolExecutor内部线程异常的四种方法,文中的示例代码讲解详细,感... 目录方案 1方案 2方案 3方案 4结论方案 1使用 execute + try-catch 记录

linux本机进程间通信之UDS详解

《linux本机进程间通信之UDS详解》文章介绍了Unix域套接字(UDS)的使用方法,这是一种在同一台主机上不同进程间通信的方式,UDS支持三种套接字类型:SOCK_STREAM、SOCK_DGRA... 目录基础概念本机进程间通信socket实现AF_INET数据收发示意图AF_Unix数据收发流程图A

Spring Boot 中正确地在异步线程中使用 HttpServletRequest的方法

《SpringBoot中正确地在异步线程中使用HttpServletRequest的方法》文章讨论了在SpringBoot中如何在异步线程中正确使用HttpServletRequest的问题,... 目录前言一、问题的来源:为什么异步线程中无法访问 HttpServletRequest?1. 请求上下文与线

在 Spring Boot 中使用异步线程时的 HttpServletRequest 复用问题记录

《在SpringBoot中使用异步线程时的HttpServletRequest复用问题记录》文章讨论了在SpringBoot中使用异步线程时,由于HttpServletRequest复用导致... 目录一、问题描述:异步线程操作导致请求复用时 Cookie 解析失败1. 场景背景2. 问题根源二、问题详细分