进程-线程-协程

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中如何正确的停掉线程》Java通过interrupt()通知线程停止而非强制,确保线程自主处理中断,避免数据损坏,线程池的shutdown()等待任务完成,shutdownNow()强制中断... 目录为什么不强制停止为什么 Java 不提供强制停止线程的能力呢?如何用interrupt停止线程s

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

python 线程池顺序执行的方法实现

《python线程池顺序执行的方法实现》在Python中,线程池默认是并发执行任务的,但若需要实现任务的顺序执行,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋... 目录方案一:强制单线程(伪顺序执行)方案二:按提交顺序获取结果方案三:任务间依赖控制方案四:队列顺序消

Linux系统管理与进程任务管理方式

《Linux系统管理与进程任务管理方式》本文系统讲解Linux管理核心技能,涵盖引导流程、服务控制(Systemd与GRUB2)、进程管理(前台/后台运行、工具使用)、计划任务(at/cron)及常用... 目录引言一、linux系统引导过程与服务控制1.1 系统引导的五个关键阶段1.2 GRUB2的进化优

SpringBoot实现虚拟线程的方案

《SpringBoot实现虚拟线程的方案》Java19引入虚拟线程,本文就来介绍一下SpringBoot实现虚拟线程的方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录什么是虚拟线程虚拟线程和普通线程的区别SpringBoot使用虚拟线程配置@Async性能对比H

在Java中实现线程之间的数据共享的几种方式总结

《在Java中实现线程之间的数据共享的几种方式总结》在Java中实现线程间数据共享是并发编程的核心需求,但需要谨慎处理同步问题以避免竞态条件,本文通过代码示例给大家介绍了几种主要实现方式及其最佳实践,... 目录1. 共享变量与同步机制2. 轻量级通信机制3. 线程安全容器4. 线程局部变量(ThreadL

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为

Java中的xxl-job调度器线程池工作机制

《Java中的xxl-job调度器线程池工作机制》xxl-job通过快慢线程池分离短时与长时任务,动态降级超时任务至慢池,结合异步触发和资源隔离机制,提升高频调度的性能与稳定性,支撑高并发场景下的可靠... 目录⚙️ 一、调度器线程池的核心设计 二、线程池的工作流程 三、线程池配置参数与优化 四、总结:线程

WinForm跨线程访问UI及UI卡死的解决方案

《WinForm跨线程访问UI及UI卡死的解决方案》在WinForm开发过程中,跨线程访问UI控件和界面卡死是常见的技术难题,由于Windows窗体应用程序的UI控件默认只能在主线程(UI线程)上操作... 目录前言正文案例1:直接线程操作(无UI访问)案例2:BeginInvoke访问UI(错误用法)案例

一文解密Python进行监控进程的黑科技

《一文解密Python进行监控进程的黑科技》在计算机系统管理和应用性能优化中,监控进程的CPU、内存和IO使用率是非常重要的任务,下面我们就来讲讲如何Python写一个简单使用的监控进程的工具吧... 目录准备工作监控CPU使用率监控内存使用率监控IO使用率小工具代码整合在计算机系统管理和应用性能优化中,监