进程-线程-协程

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

相关文章

Java多线程父线程向子线程传值问题及解决

《Java多线程父线程向子线程传值问题及解决》文章总结了5种解决父子之间数据传递困扰的解决方案,包括ThreadLocal+TaskDecorator、UserUtils、CustomTaskDeco... 目录1 背景2 ThreadLocal+TaskDecorator3 RequestContextH

java父子线程之间实现共享传递数据

《java父子线程之间实现共享传递数据》本文介绍了Java中父子线程间共享传递数据的几种方法,包括ThreadLocal变量、并发集合和内存队列或消息队列,并提醒注意并发安全问题... 目录通过 ThreadLocal 变量共享数据通过并发集合共享数据通过内存队列或消息队列共享数据注意并发安全问题总结在 J

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.

异步线程traceId如何实现传递

《异步线程traceId如何实现传递》文章介绍了如何在异步请求中传递traceId,通过重写ThreadPoolTaskExecutor的方法和实现TaskDecorator接口来增强线程池,确保异步... 目录前言重写ThreadPoolTaskExecutor中方法线程池增强总结前言在日常问题排查中,

Linux环境变量&&进程地址空间详解

《Linux环境变量&&进程地址空间详解》本文介绍了Linux环境变量、命令行参数、进程地址空间以及Linux内核进程调度队列的相关知识,环境变量是系统运行环境的参数,命令行参数用于传递给程序的参数,... 目录一、初步认识环境变量1.1常见的环境变量1.2环境变量的基本概念二、命令行参数2.1通过命令编程

Linux之进程状态&&进程优先级详解

《Linux之进程状态&&进程优先级详解》文章介绍了操作系统中进程的状态,包括运行状态、阻塞状态和挂起状态,并详细解释了Linux下进程的具体状态及其管理,此外,文章还讨论了进程的优先级、查看和修改进... 目录一、操作系统的进程状态1.1运行状态1.2阻塞状态1.3挂起二、linux下具体的状态三、进程的

python多进程实现数据共享的示例代码

《python多进程实现数据共享的示例代码》本文介绍了Python中多进程实现数据共享的方法,包括使用multiprocessing模块和manager模块这两种方法,具有一定的参考价值,感兴趣的可以... 目录背景进程、进程创建进程间通信 进程间共享数据共享list实践背景 安卓ui自动化框架,使用的是

Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单

《Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单》:本文主要介绍Springboot的ThreadPoolTaskScheduler线... 目录ThreadPoolTaskScheduler线程池实现15分钟不操作自动取消订单概要1,创建订单后

C语言线程池的常见实现方式详解

《C语言线程池的常见实现方式详解》本文介绍了如何使用C语言实现一个基本的线程池,线程池的实现包括工作线程、任务队列、任务调度、线程池的初始化、任务添加、销毁等步骤,感兴趣的朋友跟随小编一起看看吧... 目录1. 线程池的基本结构2. 线程池的实现步骤3. 线程池的核心数据结构4. 线程池的详细实现4.1 初

Java子线程无法获取Attributes的解决方法(最新推荐)

《Java子线程无法获取Attributes的解决方法(最新推荐)》在Java多线程编程中,子线程无法直接获取主线程设置的Attributes是一个常见问题,本文探讨了这一问题的原因,并提供了两种解决... 目录一、问题原因二、解决方案1. 直接传递数据2. 使用ThreadLocal(适用于线程独立数据)