进程-线程-协程

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

相关文章

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

Windows的CMD窗口如何查看并杀死nginx进程

《Windows的CMD窗口如何查看并杀死nginx进程》:本文主要介绍Windows的CMD窗口如何查看并杀死nginx进程问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Windows的CMD窗口查看并杀死nginx进程开启nginx查看nginx进程停止nginx服务

Java中实现线程的创建和启动的方法

《Java中实现线程的创建和启动的方法》在Java中,实现线程的创建和启动是两个不同但紧密相关的概念,理解为什么要启动线程(调用start()方法)而非直接调用run()方法,是掌握多线程编程的关键,... 目录1. 线程的生命周期2. start() vs run() 的本质区别3. 为什么必须通过 st

Linux实现线程同步的多种方式汇总

《Linux实现线程同步的多种方式汇总》本文详细介绍了Linux下线程同步的多种方法,包括互斥锁、自旋锁、信号量以及它们的使用示例,通过这些同步机制,可以解决线程安全问题,防止资源竞争导致的错误,示例... 目录什么是线程同步?一、互斥锁(单人洗手间规则)适用场景:特点:二、条件变量(咖啡厅取餐系统)工作流

Java中常见队列举例详解(非线程安全)

《Java中常见队列举例详解(非线程安全)》队列用于模拟队列这种数据结构,队列通常是指先进先出的容器,:本文主要介绍Java中常见队列(非线程安全)的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一.队列定义 二.常见接口 三.常见实现类3.1 ArrayDeque3.1.1 实现原理3.1.2

SpringBoot3中使用虚拟线程的完整步骤

《SpringBoot3中使用虚拟线程的完整步骤》在SpringBoot3中使用Java21+的虚拟线程(VirtualThreads)可以显著提升I/O密集型应用的并发能力,这篇文章为大家介绍了详细... 目录1. 环境准备2. 配置虚拟线程方式一:全局启用虚拟线程(Tomcat/Jetty)方式二:异步

Java进程CPU使用率过高排查步骤详细讲解

《Java进程CPU使用率过高排查步骤详细讲解》:本文主要介绍Java进程CPU使用率过高排查的相关资料,针对Java进程CPU使用率高的问题,我们可以遵循以下步骤进行排查和优化,文中通过代码介绍... 目录前言一、初步定位问题1.1 确认进程状态1.2 确定Java进程ID1.3 快速生成线程堆栈二、分析

如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socket read timed out的问题

《如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socketreadtimedout的问题》:本文主要介绍解决Druid线程... 目录异常信息触发场景找到版本发布更新的说明从版本更新信息可以看到该默认逻辑已经去除总结异常信息触发场景复