重回大学:CPU 核数 进程 线程 串行 并发 并行 同步 异步 你分清楚了吗?

本文深入浅出地介绍了计算机科学中的核心概念,包括CPU、运算器、控制器、进程、线程等,通过生动的比喻帮助理解进程与线程的区别,以及串行、并发与并行的不同之处。

前言

在学习与开发的过程中,总能听到与看到

CPU,核数, 进程, 线程, 并行度, 串行, 并发, 并行, 同步, 异步  . . . . . .

这些东西,有时候在很相近的地方的一时半会区分一个1,2,3来,真的是说不上来。所以特意总结一篇。

其实这就是在大学学习《计算机组成原理》的内容。当时学习的时候,不能理解学习完这些就是知道了有啥用,现在工作几年了,回想起来真的很有用。对于还在大学的读者,要好好学习基础知识。所以,今天此篇是来重新从老师那边拿回咱们的东西,回想你的大学,还记得这位老师吗?来评论聊聊。

 

CPU

中央处理器,其功能主要是解释计算机指令以及处理计算机软件中的数据。CPU是计算机中负责读取指令,对指令译码并执行指令的核心部件。

运算器

(1)算术逻辑单元(ALU)。算术逻辑单元的运算主要是进行二位元算术运算,如加法、减法、乘法。在运算过程中,算术逻辑单元主要是以计算机指令集中执行算术与逻辑操作,通常来说,ALU能够发挥直接读入读出的作用,具体体现在处理器控制器、内存及输入输出设备等方面,输入输出是建立在总线的基础上实施。输入指令包含一 个指令字,其中包括操作码、格式码等。

(2)累加器(accumulator)是一种寄存器,用来储存计算产生的中间结果。如果没有像累加器这样的寄存器,那么在每次计算 (加法,乘法,移位等等) 后就必须要把结果写回到内存,也许马上就得读回来。

(3)状态寄存器用来存放两类信息:一类是体现当前指令执行结果的各种状态信息(条件码),如有无进位(CF位)、有无溢出(OV位)、结果正负(SF位)、结果是否为零(ZF位)、奇偶标志位(P位)等;另一类是存放控制信息(PSW:程序状态字寄存器),如允许中断(IF位)、跟踪标志(TF位)等

(4)通用寄存器。用于暂时存放或传送数据或指令。

控制器

控制器,是计算机的指挥中心,负责决定执行程序的顺序,给出执行指令时机器各部件所需要的操作控制命令。

(1)程序计数器(PC)。用来存储从内存提取的下一条指令的地址。当CPU执行一条指令时,首先需要根据PC中存放的指令地址,将指令由内存取到指令寄存器中,此过程称为“取指令”。与此同时,PC中的地址或自动加1或由转移指针给出下一条指令的地址,此后经过分析指令,执行指令,完成第一条指令的执行,而后根据PC取出第二条指令的地址,如此循环,执行每一条指令,保证程序能够连续地执行下去。

(2)指令编译器。用于翻译指令及控制传输指令包含的数据。

(3)指令寄存器。用于缓存从内存或高速缓存里取出的指令,CPU执行指令时,就可以从指令寄存器中取出相关指令来进行执行。

(4)时序产生器。类似于“时间作息表”,给计算机各部分提供工作所需的时间标志,一般是利用定时脉冲的顺序和不同的脉冲间隔来实现。

(5)操作控制器。根据指令所需完成的操作和信号,发出各种微操作命令序列,用以控制所有被控对象,完成指令的执行。

核数

CPU核数即一个CPU由多少个核心组成,核心数越多,代表这个CPU的运转速度越快,性能越好。对于同一个数据处理,一核CPU相当于1个人处理数据,双核CPU相当于2个人处理同一个数据,4核CPU相当于4个人去处理同一个数据,因此处理核心数越多,CPU的工作效率也就越高。以windows为例:

插槽:1个CPU 内核:4核数 逻辑处理器:8线程

所以对于图片上的这台电脑看,这是一台单CPU 4核 8线程的电脑。

对于概念上来看,4核心指的的物理概念,8线程是逻辑概念。这是利用超线程技术将一个物理核心模拟为2个核心,这2个核心并不是物理上独立存在的电路,所以叫做逻辑核(逻辑处理器)。

多核与多CPU

多核,是指一个CPU有多个核心处理器,处理器之间通过CPU内部总线进行通讯。

多CPU是指简单的多个CPU工作在同一个系统上,多个CPU之间的通讯是通过主板上的总线进行的。

进程

进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。

结构

(1)文本区域:存储处理器执行的代码。

(2)数据区域:存储变量和进程执行期间使用的动态分配的内存。

(3)堆栈:存储着活动过程调用的指令和本地变量。

状态(就绪、运行和阻塞)

(1)就绪

阻塞态到就绪态:阻塞的进程获得等待的资源或信号。

运行态到就绪态:时间片轮转的情况下,进程的时间片用完。

运行态到就绪态:CPU调度给优先级更高的进程。

(2)运行态

正在运行的进程

(3)阻塞态

等待资源,信息交换,进程同步(停下来等待其他进程),这些情况都会存在阻塞。

线程

一个进程中可以包含若干个线程。线程可以利用进程所拥有的资源,在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位,由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统多个程序间并发执行的程度。

状态

(1)新建状态(new):新创建了一个线程。

(2)就绪状态(Runnable):线程对象创建后,该状态的线程位于可运行线程池 中,变得可运行,等待被线程调度选中,获取cpu的使用权。在java中调用了start()方法。

(3)运行状态(Running):就绪状态的线程获取了CPU时间片,执行程序代码。

(4)阻塞状态(Blocked):阻塞状态是线程因为种种原因丢掉了CPU使用,暂时停止运行。

(5)死亡状态(Dead):线程执行完了或者遇到异常,该线程结束生命周期。

进程与线程

有个形象的比喻就是:进程好比是火车,线程好比是车厢(多线程)。

对比项进程线程
定义进程是程序运行的一个实体的运行过程,是系统进行资源分配和调配的一个独立单位线程是进程运行和执行的最小调度单位
系统性能创建撤销切换影响性能,资源要重新分配和收回仅保存少量寄存器的内容,在进程的地址空间执行代码
拥有资产资源拥有的基本单位基本上不占资源,仅有不可少的资源(程序计数器,一组寄存器和栈)
调度资源分配的基本单位独立调度分配的单位
安全性进程间相互独立,互不影响线程共享一个进程下面的资源,可以互相通信
地址空间赋予的独立的内存地址空间由相关堆栈寄存器和和线程控制表组成,寄存器可被用来存储线程内的局部变量

串行,并发与并行

串行: 多个任务,执行时一个执行完再执行另一个。

并发: 多个线程在单个核心运行,同一时间一个线程运行,系统不停切换线程,看起来像同时运行,实际上是线程不停切换。

并行: 每个线程分配给独立的核心,线程同时运行。

在单CPU系统中,系统调度在某一时刻只能让一个线程运行,虽然这种机制有多种形式,但是大多数是时间片轮询方式为主,要通过不断切换需要运行的线程让其运行的方式就叫并发(concurrent)。而在多CPU系统中,可以让两个以上的线程同时运行,这种可以同时让两个以上线程同时运行的方式叫做并行(parallel)

所以记住:并发在微观上不是同时执行的,只是把时间分成若干段,使多个线程快速交替的执行。在软件领域,完成多个任务需要借助多线程完成。但是并不是并发操作能够完全优势于串行操作,因为线程间切换需要成本,但是有时候有些任务只能通过串行完成。

其他方式的理解

串行:打完游戏去睡觉。

并发:指两个或多个事件在同一时间间隔发生,交替做不同事情的能力。比如:上班的时候正在写代码,中间的时候领导让开了会,开完会,继续写代码。

并行:指两个或者多个事件在同一时刻发生,同时做不同事情的能力。比如:习惯性的边吃饭边看视频。

同步与异步

同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去。

异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。

当多个线程需要访问同一个资源时,它们需要以某种顺序来确保该资源在某一特定时刻只能被一个线程所访问,如果使用异步,程序的运行结果将不可预料。因此,在这种情况下,就必须对数据进行同步,即限制只能有一个进程访问资源,其他线程必须等待。

所以同步与异步的选择要看业务场景。

<think>首先,用户的问题是:“我想了解Python中串行并行的概念及实现方式请问Python串行并行处理的区别及实现方法”。用户提供了站内引用,包括引用[1]到[5],我需要参考这些引用来回答。引用内容总结:-[1]:讨论并行计算的方法,如多进程(multiprocessing.Process),用于绕过GIL的限制,适合CPU密集型任务。还提到concurrent.futures。-[2]:描述用map函实现并行,使用multiprocessing或multiprocessing.dummy(线程池)。强调并行化map函的便利性。-[3]:线程的创建方式,使用threading.Thread,代码示例展示了多线程执行任务。-[4]:提到协程并行处理,协程池,速率控制,以及串行并行的对比。-[5]:解释串行并行处理的区别,并发的概念,以及它们如何通过CPU时间片实现。系统级指令:-所有行内学表达式必须使用$...$,但由于用户问题不涉及学,我可能不需要它,除非有学内容。-独立公式使用$$...$$单独成段,同样,可能不适用。-LaTeX语法正确:确保如果有学表达式,使用正确的LaTeX。-使用中文回答。-生成相关问题:在回答结尾添加相关问题列表。-引用中添加引用标识:例如[^1],在引用的段落末尾添加。-回答结构清晰,逐步解决问题。用户上次的问题是隐式的,因为在用户消息中没有历史;只有系统指令和当前问题。所以,我需要基于当前查询。我的回答结构:1.解释串行并行的概念。2.在Python中的实现方式。-串行:简单顺序执行。-并行:-多线程:threading,ThreadPool(multiprocessing.dummy)-多进程:multiprocessing.Process-协程:asyncio,concurrent.futures-参考引用中的例子。3.区别:-性能:并行适合IO密集或CPU密集任务。-GIL限制:线程受到GIL限制,进程不。-同步异步。4.添加相关示例代码片段(可选,因为用户提供了例子,我可以引用)。5.结束生成相关问题。生成相关问题:在末尾添加3-5个相关问题,使用§§相关问题§§格式。确保回答可靠:基于标准Python知识和引用内容。大纲回答:-引言:概述串行并行。-串行处理:解释概念和简单例子。-并行处理:-线程:基于[3]和[5],用于IO密集。-进程:基于[1],用于CPU密集。-协程:基于[4],异步IO。-并发库:concurrent.futures[^1]。-区别:基于[5],并行vs并发,性能影响。-实现代码:参考提供的代码片段。-总结:何时使用什么。-相关问题列表。语言:中文。添加引用标识:例如,当提到引用内容时,在末尾加[^n]。例如:"在Python中,串行处理是指任务的顺序执行,一个接一个。并行处理则是同时执行多个任务,提升效率[^5]。"相关问题生成:-针对串行并行的常见错误?-如何优化并行代码?-Python中并行计算的GIL问题如何解决?-实际应用场景?-协程与线程的区别?</think> ### Python 串行并行处理的区别及实现方法 在Python编程中,处理任务的方式为**串行处理**和**并行处理**,它们直接影响程序的性能和效率。下面我将逐步解释两者的概念、区别,并结合Python的实现方式,包括代码示例,确保内容清晰易懂。回答中引用了提供的站内资料,力求准确可靠。 #### 1. **串行处理的概念与实现** **概念**:串行处理是指任务依次执行,即在一条流水线上完成:一个任务开始、执行、结束后,才进行下一个任务。这种方式简单直观,但效率较低,因为它不利用多CPU的资源[^5]。 **区别心**:串行本质是顺序操作,适用于任务间依赖性强或据共享高的场景;并行则能同时处理多个任务。 **Python实现**:Python默认执行模式是串行的,可通过普通函或循环实现,无需额外库。例如,一个串行任务示例: ```python # 串行示例:顺序计算任务 import time def task(n): time.sleep(1) # 模拟耗时操作 return n * n start = time.time() results = [] for i in range(3): results.append(task(i)) print(f"串行结果: {results}, 耗时: {time.time() - start:.2f}秒") # 输出类似: 串行结果: [0, 1, 4], 耗时: 3.00秒(每个任务耗时1秒) ``` 在这个例子中,任务循环调用 `task` 函,顺序执行,每个任务等待前一个完成(如 `time.sleep` 模拟IO等待)。串行处理的限制是CPU利用率低,不适合高负载任务[^4]。 #### 2. **并行处理的概念与实现** **概念**:并行处理是指多个任务同时执行,通常利用多CPU资源(如进程并行)或异步机制(如线程、协程并行),提升效率。并行适用于IO密集型或CPU密集型任务[^1][^5]。并行与**并发**(concurrency)的区别在于:并行是真正同时运行任务(如多进程),并发是任务通过切换时间片模拟“同时”(如多线程受GIL限制)[^5]。 **心区别**: - **并行**:物理同时执行(多个CPU心)。 - **并发**:逻辑同时执行(单个CPU切换任务)。 并行处理在Python中主要有三种实现方式: **a. 多线程(Threading)** 适用于IO密集型任务(如网络请求),因为线程共享内存资源,切换开销小。但受Python的全局解释器锁(GIL)限制,无法真正利用多CPU并行计算[^3][^5]。 **实现示例**:使用 `threading` 模块创建线程池(dummy模块)。 ```python # 并行线程示例:模拟IO任务 from threading import Thread import time def worker(num): time.sleep(1) # 模拟IO操作 print(f"Worker: {num} 完成") start = time.time() threads = [] for i in range(3): t = Thread(target=worker, args=(i,)) threads.append(t) t.start() # 启动线程 for t in threads: t.join() # 等待所有线程结束 print(f"并行线程耗时: {time.time() - start:.2f}秒") # 输出类似: Worker: 0 完成\nWorker: 1 完成\nWorker: 2 完成耗时约1秒 ``` 在这个例子中,多个线程同时启动,共享 `worker` 函。通过线程池(如 `multiprocessing.dummy` 的 `Pool`),能更简化并行 `map` 操作[^2]。 **b. 多进程(Multiprocessing)** 适用于CPU密集型任务(如学计算),因为每个进程独立运行,绕过GIL限制,完全利用多CPU[^1][^5]。 **实现示例**:使用 `multiprocessing.Process` 或 `concurrent.futures`。 ```python # 并行进程示例:CPU密集型任务 from multiprocessing import Process import time def task(num): # 模拟CPU计算 start = time.perf_counter() _ = sum(i*i for i in range(10**6)) # 大量计算 print(f"Process {num} 完成, 用时: {time.perf_counter() - start:.2f}秒") start = time.time() processes = [] for i in range(3): p = Process(target=task, args=(i,)) processes.append(p) p.start() for p in processes: p.join() print(f"并行进程总耗时: {time.time() - start:.2f}秒") # 输出类似: Process 0 完成... 总耗时约最大单任务时间(并行加速) ``` 使用 `concurrent.futures` 的线程池或进程池可进一步简化: ```python from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor # 线程池(适合IO) with ThreadPoolExecutor(max_workers=3) as executor: results = list(executor.map(worker, range(3))) # 进程池(适合CPU) with ProcessPoolExecutor() as executor: results = list(executor.map(task, range(3))) # map函简化并行[^1][^2] ``` **c. 协程(Coroutines)** 适用于高并发IO任务(如Web请求),协程是轻量级线程,通过异步非阻塞操作提升吞吐量。协程池控制速率,避免资源消耗过大[^4]。 **实现示例**:使用 `asyncio` 库或 `concurrent.futures` 结合 async/await。 ```python # 并行协程示例:异步IO任务 import asyncio async def async_worker(num): await asyncio.sleep(1) # 异步IO等待 return num async def main(): tasks = [async_worker(i) for i in range(3)] results = await asyncio.gather(*tasks) # 并行执行 print(f"协程结果: {results}, 用时短") asyncio.run(main()) # 输出: 协程结果: [0, 1, 2], 用时约1秒(相比串行大幅提速) ``` 协程的优势在于高并发下的效率,但需要事件循环支持[^4]。 #### 3. **心区别总结** - **性能影响**: - 串行:效率低,耗时线性增长(时间 ∝ 任务)。 - 并行:效率高,耗时接近最大单任务时间(近似 $O(1)$ 加速比),但进程间通信(IPC)可能带来开销[^1][^5]。 - **适用场景**: - 串行:任务依赖强(如顺序据处理)、简单脚本。 - 并行CPU密集(多进程)、IO密集(多线程或协程)[^1][^4]。 - **风险点**:并行可能导致竞态条件(需同步机制),资源消耗高;串行则易于调试但扩展性差[^3][^5]。 实际项目中,选择依据任务类型:IO密集型用线程或协程,CPU密集型用进程。工具上, `concurrent.futures` 库统一管理并行模式[^1][^2][^4]。 #### 4. **注意事项与最佳实践** - **GIL问题**:线程并行受GIL限制,不适合纯计算;用多进程规避[^1]。 - **错误处理**:并行中异常传播需 `try-except` ,用 `futures` 库封装易管理。 - **性能权衡**:并行加速非无限,Amdahl定律 $S = \frac{1}{(1 - P) + \frac{P}{N}}$ 表明,并行 $P$ 越大,加速比 $S$ 越高($N$ 为)[^5]。 - **推荐工具**:优先用 `concurrent.futures` 或 `asyncio`,简化代码。 Python的并行处理能显著提升效率,但需根据任务特征选择正确模式,避免过度设计或资源浪费[^4][^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值