Python 并行与并发详解!

Python 并发与并行 并发(Concurrency)和并行(Parallelism)是现代编程中的两个重要概念。它们帮助我们充分利用计算资源(如 CPU 核心和 I/O 资源),提升程序性能。然而并发和并行有着不同的适用场景和实现方式。 阅读详情

在 Python 中关于并发/并行的实现方式(库)有很多,于是我打算做个总结方便今后查阅。其实查阅文档,别的不好说,对于 Python,最好的方式就是查阅官方文档,除了少了些例子,几乎是完美的,所以本文只会列出常用的方法与属性。

基础概念

并行

Python学习交流群:1004391443

并行(parallelism),就是同时执行的意思,所以单线程永远无法达到并行状态,利用多线程和多进程即可。但是 Python 的多线程由于存在著名的 GIL,无法让两个线程真正“同时运行“,所以实际上是无法到达并行状态的。就像 2 个人同时吃 2 个包子,最后两个包子同时被吃完。

并发

并发(concurrency),整体上来看多个任务同时进行,但是一个时间点只有一个任务在执行。就像 1 个人同时吃 2 个包子,一次一边咬一口,最后差不多是两个包子同时被吃完。

多进程

  1. 进程:程序是指令、数据及其组织形式的描述,进程是程序的实体。
  2. 子进程:子进程指的是由另一进程(对应称之为父进程)所创建的进程。
  3. 多进程:实现并行的手段,多进程的数量取决于 CPU 核心的数量。

多线程

  1. 线程:轻量级进程。线程是进程中的一个实体(一个进程至少有一个线程),是被系统独立调度和分派的基本单位(即操作系统能够进行运算调度的最小单位)。
  2. 多线程:实现并发的手段,多线程数量根据实际需要来确定,但是也是有上限的。

线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。

实现方式

多进程

fork

Unix/Linux 操作系统提供了一个 fork() 系统调用,它非常特殊。普通的函数,调用一次,返回一次,但是 fork() 调用一次,返回两次 ,因为操作系统自动把当前进程(父进程)复制了一份(子进程),然后,分别在父进程和子进程内返回。子进程永远返回 0 ,而父进程返回子进程的 ID。这样做的理由是,一个父进程可以 fork 出很多子进程,所以,父进程要记下每个子进程的 ID,而子进程只需要调用 getpid() 就可以拿到父进程的 ID。

而在 Python 中, os 模块封装了常见的系统调用,其中就包括 fork ,可以在 Python 程序中轻松创建子进程:

import os
print('Process (%s) start...' % os.getpid())
# Only works on Unix/Linux/Mac:
pid = os.fork()
if pid == 0:
    print('I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid()))
else:
    print('I (%s) just created a child process (%s).' % (os.getpid(), pid))

结果:

Process (876) start...
I (876) just created a child process (877).
I am child process (877) and my parent is 876.

有了 fork ,一个进程在接到新任务时就可以复制出一个子进程来处理新任务,常见的 Apache 服务器就是由父进程监听端口,每当有新的 http 请求时,就 fork 出子进程来处理新的 http 请求。

subprocess

有时候,子进程并不是代码自身,而是一个外部进程。Python 标准库中的 subprocess 库就可以 fork 一个子进程,来运行一个外部的程序,还可以接管子进程的输入和输出。

subprocess 中定义了多个函数,它们以不同的方式创建子进程(call、check_call、check_output、Popen 等等),根据不同需要来选取即可。另外 subprocess 还提供了一些接管标准流(standard stream)和打通管道(pipe)的工具,从而在进程间使用文本通信。

下面的例子演示了如何在 Python 代码中运行命令 nslookup www.python.org ,这和命令行直接运行的效果是一样的:

import subprocess
print('$ nslookup www.python.org')
r = subprocess.call(['nslookup', 'www.python.org'])
print('Exit code:', r)

结果

$ nslookup www.python.org
Server:        192.168.19.4
Address:    192.168.19.4#53
Non-authoritative answer:
www.python.org    canonical name = python.map.fastly.net.
Name:    python.map.fastly.net
Address: 199.27.79.223
Exit code: 0

multiprocessing

如果要编写多进程的服务程序,Unix/Linux 无疑是正确的选择,由于 Windows 没有 fork 调用,上面的代码在 Windows 上无法运行。但是 Python 是跨平台的,自然也应该提供一个跨平台的多进程支持。于是就出现了 multiprocessing 。

multiprocessing 模块就是跨平台的多进程模块。在 Unix/Linux 下, multiprocessing 模块封装了 fork() ,使我们不需要关注 fork() 的细节。由于 Windows 没有 fork 调用,因此, multiprocessing 需要“模拟”出 fork 的效果,父进程所有 Python 对象都必须通过 pickle 序列化再传到子进程去所有。

所以,如果 multiprocessing 在 Windows 下调用失败了,要先考虑是不是 pickle 失败了。

multiprocessing 模块常见的使用方式:

multiprocessing 模块提供了一个 Process 类来代表一个进程对象:

创建进程的类

Process([group [, target [, name [, args [, kwargs]]]]])

描述:

  1. 由该类实例化得到的对象,表示一个子进程中的任务(尚未启动),下面称之为 p

注意:

  1. args:指定的为传给 target 函数的位置参数,是元组的形式。

参数:

args=('arg1', )
kwargs={'name': 'hexin', 'age': 18}

方法:

  1. p.start() :启动进程,并调用该子进程中的 p.run()
  2. p.run() :进程启动时运行的方法,正是它去调用 target 指定的函数,若继承 Process 类来写多进程的话,自定义的类中一定要实现该方法。
  3. p.terminate() :强制终止进程 p,不会进行任何清理操作,如果 p 创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果 p 还保存了一个锁那么也将不会被释放,进而导致死锁。
  4. p.is_alive() :如果 p 仍在运行,返回 True
  5. p.join([timeout]) :主线程等待 p 终止(即主线程处于等的状态,而 p 是处于运行的状态)。timeout 是可选的超时时间(超过这个时间,父线程不再等待子线程,继续往下执行),注意, p.join() 只能 join 住 start 开启的进程,而不能 join 住 run 开启的进程

属性:

p.daemon
p.name
p.pid

示例:

注意:在 windows 中使用 Process() 必须放到 if __name__ == '__main__': 下

下面的例子演示了启动一个子进程并等待其结束:

from multiprocessing import Process
import os
# 子进程要执行的代码
def run_proc(name):
    print('Run child process %s (%s)...' % (name, os.getpid()))
print('Parent process %s.' % os.getpid())
p = Process(target=run_proc, args=('test',))
print('Child process will start.')
p.start()
p.join()
print('Child process end.')

创建子进程时,只需要传入一个执行函数和函数的参数,创建一个 Process 实例,用 start() 方法启动,这样创建进程比 fork() 还要简单。

join() 方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步。

当然,也可以使用类,继承 Process 来创建子进程:

import time
import random
from multiprocessing import Process
class MyProcess(Process):
    def __init__(self,name):
        super().__init__()
        self.name = name
    def run(self):
        print('%s running' %self.name)
        time.sleep(random.randrange(1,5))
        print('%s stop' %self.name)
p1 = MyProcess('1')
p2 = MyProcess('2')
p3 = MyProcess('3')
p4 = MyProcess('4')
p1.start() # start 会自动调用 run
p2.start()
p3.start()
p4.start()
print('主线程')

结果

1 running
2 running
主线程
3 running
4 running
1 stop
4 stop
2 stop
3 stop

Pool([numprocess [,initializer [, initargs]]])

那么问题来了,开多进程的目的是为了并发,如果有多核,通常有几个核就开几个进程,进程开启过多,效率反而会下降(开启进程是需要占用系统资源的,而且开启多余核数目的进程也无法做到并行),但很明显需要并发执行的任务常常远大于核数,这时我们就可以通过维护一个进程池来控制进程数目,比如 httpd 的进程模式,规定最小进程数和最大进程数等。

当进程数目不大时,可以直接利用 multiprocessing 中的 Process 类手动创建多个进程,如果数量很大,就需要使用进程池。Pool 类可以提供指定数量的进程,供用户调用,当有新的请求提交到 Pool 中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,就重用进程池中的进程。

参数:

  1. numprocess:要创建的进程数,如果省略,将默认使用 cpu_count()的值
  2. initializer:是每个子进程启动时要执行的可调用对象,默认为 None
  3. initargs:是要传给 initializer 的参数组

方法:

  1. p.apply(func[, args[, kwargs]]) :在一个进程池的所有进程中执行 func(*args,**kwargs) ,然后返回结果。注意:若同时进行 2 apply,则按照顺序执行,所以这个函数是阻塞型的,阻塞的对象是主进程与各个子进程。这函数从 py2.3 以后就不建议使用了
  2. apply_async(func[, args[, kwds[, callback[, error_callback]]]]) :在一个进程池的所有进程中执行 func(*args, **kwargs) ,然后返回结果,此方法的结果是 AsyncResult 类的实例(下面会说)。callback 是可调用对象,接收输入参数。当 func 的结果变为可用时,将立即传递给 callback,callback 禁止执行任何阻塞操作,否则会收到其他异步操作中的结果。error_callback 是在函数执行出错的时候调用。注意,apply_async 不是阻塞型的。
  3. p.map(func, iterable[, chunksize=None]) :Pool 类中的 map 方法,与内置的 map 函数用法行为基本一致,它会使进程阻塞直到返回结果。注意,虽然第二个参数是一个迭代器,但是它只在整个队列都就绪后,程序才会运行子进程。注意:此时 func 必须要接受一个参数,参数来源于 iterable 中的每个元素。这个函数是阻塞型的,阻塞的对象是主进程。
  4. map_async(func, iterable[, chunksize[, callback[, error_callback]]]) : map_async 与 map 的关系同 apply 与 apply_async,即这个这个函数不是阻塞型的。map_async 与 apply_async 都是异步的,所以需要有个回调函数,也就是通过 callback 参数来指定。当然,error_callback 也是一样的
  5. p.close() :关闭进程池,防止进一步操作。
  6. p.terminate() :结束子进程,不再处理未处理的任务。
  7. p.join() :等待所有子进程结束。注意:此方法只能在 close() 或 teminate() 之后调用,即让进程池不再接受新的任务。

其他方法:

apply_async() 和 map_async() 的返回值是 AsyncResul ,这个实例具有以下方法

  1. obj.get([timeout]) :返回结果,如果有必要则等待结果到达。timeout 参数是可选的。如果在指定时间内还没有到达,将引发异常。如果在子进程中出现了异常,那么异常将在调用此方法时再次被抛出。(侧重于 拿)
  2. obj.wait([timeout]) :等待返回的结果到达,timeout 参数是可选的。如果在指定时间内还没有等到,则直接执行后续代码。(侧重于 等)
  3. obj.ready() :如果调用完成,返回 True
  4. obj.successful() :如果调用完成且没有引发异常,返回 True,如果在结果就绪之前调用此方法,则会引发异常( ValueError: <multiprocessing.pool.ApplyResult object at xxxxx> not ready )

例子:

from multiprocessing import Pool
import os, time, random
def long_time_task(name):
    print('Run task %s (%s)...' % (name, os.getpid()))
    start = time.time()
    time.sleep(random.random() * 3)
    end = time.time()
    print('Task %s runs %0.2f seconds.' % (name, (end - start)))
print('Parent process %s.' % os.getpid())
p = Pool(4)
for i in range(5):
    p.apply_async(long_time_task, args=(i,))
print('Waiting for all subprocesses done...')
p.close()
p.join()
print('All subprocesses done.')

结果

Parent process 669.
Waiting for all subprocesses done...
Run task 0 (671)...
Run task 1 (672)...
Run task 2 (673)...
Run task 3 (674)...
Task 2 runs 0.14 seconds.
Run task 4 (673)...
Task 1 runs 0.27 seconds.
Task 3 runs 0.86 seconds.
Task 0 runs 1.41 seconds.
Task 4 runs 1.91 seconds.
All subprocesses done.

注意输出的结果,task 0 , 1 , 2 , 3 是立刻执行的,而 task 4 要等待前面某个 task 完成后才执行,这是因为 Pool 的默认大小在我的电脑上是 4,因此,最多同时执行 4 个进程。这是 Pool 有意设计的限制,并不是操作系统的限制。如果改成: p = Pool(5) 就可以同时跑 5 个进程(但是就不是并行了,而是并发)。由于 Pool 的默认大小是 CPU 的核数,如果你 不幸 拥有 8 核 CPU,你要提交至少 9 个子进程才能看到上面的等待效果(逃)。

又一个例子:

提交任务,并在主进程中拿到结果(之前的 Process 是执行任务,结果放到队列里,现在可以在主进程中直接拿到结果)

from multiprocessing import Pool
import time
def work(n):
    print('开工啦...')
    time.sleep(3)
    return n ** 2
q = Pool()
# 异步 apply_async 用法:如果使用异步提交的任务,主进程需要使用 join,等待进程池内任务都处理完,然后可以用 get 收集结果,否则,主进程结束,进程池可能还没来得及执行,也就跟着一起结束了
res = q.apply_async(work, args=(2,))
q.close()
q.join() #join 在 close 之后调用
print(res.get())
# 同步 apply 用法:主进程一直等 apply 提交的任务结束后才继续执行后续代码
# res = q.apply(work, args=(2,))
# print(res)

结果

开工啦...
4

对 Pool 对象调用 join() 方法会等待所有子进程执行完毕,调用 join() 之前必须先调用 close() ,调用 close() 之后就不能继续添加新的 Process 了。 

Python 多线程教程:并发与并行 附Java/C/C++/机器学习/算法与数据结构/前端/安卓/Python/程序员必读书籍书单大全: 书单导航页(点击右侧 极客侠栈 即可打开个人博客):极客侠栈 ①【Java】学习之路吐血整理技术书从入门到进阶最全50+本(珍藏版) ②【算法数据结构+acm】从入门到进阶吐血整理书单50+本(珍藏版) ③【数据库】从入门到进阶必读18本技术书籍网盘吐血整理网盘(珍藏版) ④【Web前端】从HT... 阅读详情

相关推荐

Python中的并发、并行与异步处理:简单入门指南

Python中的并发、并行与异步处理:简单入门指南

engchina的专栏 1196

Python笔记:并发(Concurrency)和并行(Parallelism)是计算机科学中两个相关但不同的概念。

并发可以通过时间分片或者任务切换来实现,从用户的角度看,多个任务在同时执行,提升了系统的响应性和吞吐量。而在多核处理器上,不同的任务可以并行在多个核心上执行。在一个系统中,可以有多个并发任务,每个任务内部可能还存在并行的子任务。通过合理的设计和利用多核处理器的能力,可以在并发和并行的双重优势下提高系统的效率和性能。而并行需要多个处理单元,可以在多核处理器或者分布式系统上实现任务的加速。并行执行的多个任务可以利用多个处理单元(如多个CPU核心)来同时执行,从而加速任务的完成。是指两个或多个任务在。

weixin_45381278的博客 399

并发 Vs 并行

本文主要讲解了 1.并发和并行两个概念的区别 2. Python中multiprocessing多进程库的使用

Ethan's Blog 712

python3.8 multiprocess.Pool.apply_async一个很大的坑

假如你apply_async(func=self.***,args=(***)) 你这个func函数写在同一个类下面,即self下面,是无法异步运行的,实际上还是排队运行!!!!! 切记切记,func一定要在另一个类里写!!!!!! 如果有帮助到你,请给我点赞留言,给我点成就感,谢谢!!! ...

weixin_43595259的博客 2926

matlab球面投影(二)

matlab球面投影,想做一个全景相机,不知道,要做成啥样,于是在MATLAB先仿真一下,看下是个啥样子 百度别人做的,复制下面的代码到MATLAB的命令串口下,,网上找了张全景图,可以是bmp,jpg,改程序就可以了 回车运行就可以看到结果。 复制下面代码时,下面的中文注释记得删除,MATLAB是会报错的, close all; clear all; clc [x,y,z]=sphere(50); A=imread('a.JPG'); //名字是自己命名的,记得改 B=warp(x,y,-z,

rjszcb的博客 3165

S7-1200 Modbus TCP客户端配置实战:从基础设置到数据交互详解

本文详细介绍了S7-1200 Modbus TCP客户端的配置方法,从基础设置到数据交互的完整流程。涵盖硬件准备、TIA Portal配置、MB_CLIENT指令参数详解、数据缓冲区管理及实战测试,帮助工程师快速掌握西门子PLC与Modbus TCP通信的关键技术。

fire9的博客 311

Python学习笔记之进程池pool

Pool类可以提供指定数量的进程供用户调用,当有新的请求提交到Pool中时,如果池还没有满,就会创建一个新的进程来执行请求。如果池满,请求就会告知先等待,直到池中有进程结束,才会创建新的进程来执行这些请求。

json_li的博客 5885

基于MATLAB实现的克里金插值的代码

参考代码 克里金插值matlab代码 youwenfan.com/contentcsb/81657.html。

jghhh01的博客 483

python multiprocessing apply_async(),调用本类的方法失败

这个func函数写在同一个类下面,即self下面,是无法异步运行的,实际上还是排队运行!func一定要在本类外面写!

LlanyW的专栏 924

红外避障模块介绍

该传感器模块对环境光线适应能力强,其具有一对红外线发射与接收管,发射管发射出一定频率的红外线,当检测方向遇到障碍物(反射面)时,红外线反射回来被接收管接收,经过比较器电路处理之后,绿色指示灯会亮起,同时信号输出接回输出数字信号(一个低电平信号),可通过电位器旋钮调节检测距离,有效距离范围2~30cm,工作电压为3.3v-5v。该模块测距离2~~30cm,检测角度35°,检测距离可以通过电位器进行调节,顺时针调电位器,检测距离增加;1.VCC外接3.3v-5v电压(可以直接与5v单片机和3.3v单片机相连).

weixin_46251230的博客 2万+

拆解维修指南:当你的大扭矩电动扳手‘罢工’,如何自己动手排查行星齿轮与谐波传动故障?

本文详细解析了大扭矩电动扳手行星齿轮与谐波传动故障的排查与修复方法。从故障初判、拆解工艺到行星齿轮系统检测、谐波传动维护,提供了一套完整的维修指南,帮助用户快速诊断和解决常见问题,延长工具使用寿命。

weixin_42525582的博客 436

并行执行(二)、multiprocessing

multiprocessing模块 multiprocessing包是Python中的多进程管理包。它与 threading.Thread类似,可以利用multiprocessing.Process对象来创建一个进程。该进程可以允许放在Python程序内部编写的函数中。该Process对象与Thread对象的用法相同,拥有is_alive()、join([timeout])、run()、star.........

weixin_36670529的博客 1252

FPGA纯Verilog实现I²C主机控制器与EEPROM读写

I²C是一种广泛应用的同步串行总线协议,用于连接微控制器与EEPROM、传感器等低速外设。其核心原理包括开漏结构、主从通信机制、START/STOP时序及ACK/NACK应答流程。技术价值在于硬件资源占用少、布线简洁、支持多从机扩展,特别适合FPGA嵌入式系统中轻量级外设控制。典型应用场景涵盖工业数据存储、配置参数持久化及实时传感器接口。本文基于Xilinx Spartan-6 FPGA,采用纯Verilog HDL实现参数化I²C主机控制器与AT24C02 EEPROM读写验证,深入解析状态机设计、SDA

weixin_33557333的博客 119

深入理解并行与并发:C++/Python实例详解

并发是指在同一时间段内处理多个任务的能力。并发并不一定意味着这些任务是同时执行的,而是指多个任务在逻辑上是同时进行的。并发可以通过时间分片(time-slicing)来实现,即在一个处理器上快速切换任务,使得用户感觉到多个任务在同时进行。特点任务可以在同一时间段内交替执行。适用于 I/O 密集型任务(如网络请求、文件读写等)。主要关注任务的管理和调度。并发和并行是处理多个任务的两种不同方式,前者强调任务的管理和调度,后者强调任务的同时执行。

码事漫谈 2318

GPU 资源池化云平台解决方案​

定义与特点Kubernetes是一个开源的容器编排和管理平台,通过提供自动化和声明式的方式来部署、扩展、维护和运行应用程序。它支持跨多个主机和集群部署容器,确保应用程序的高可用性和可扩展性。Kubernetes提供了丰富的功能和插件,允许用户根据自己的需求进行定制和扩展。架构与组件控制平面(Control Plane):负责集群的决策(如调度)和集群状态的检测与响应。

ZhangJiqun&191cm&85kg 1162

YOLO26 无损剪枝:稀疏训练 + 结构化通道裁剪

YOLO26 无损剪枝链路:YOLO26s (7.2M) → 稀疏训练 30 epoch (L1 on BN gamma, lam=0.01) → 阈值剪枝 50% (gamma<quantile(0.5)) → 结构化重建 Conv+BN → 微调 10 epoch (lr=1e-4) → YOLO26n (1.9M, mAP50 0.808, 仅降 0.6%)。核心贡献:稀疏训练让 BN gamma 趋向二元分布 (近 0 或近 1), 剪枝阈值可直接取 median 自动 50% 压缩。

m0_64661770的博客 263

【Python】并发与并行

GIL(Global Interpreter Lock,全局解释器锁)是Python解释器为了简化内存管理和保证线程安全而引入的一种机制。GIL限制了在同一时间只能有一个线程执行Python字节码,从而防止多线程并发访问共享数据导致的不一致问题。性能开销:GIL 的存在使得在 CPython 中执行 CPU 密集型任务的多线程性能不高,因为每次线程切换都需要竞争 GIL,带来资源开销。因此,对于 CPU 密集型任务,推荐使用多进程(例如模块)以充分利用多核 CPU。I/O 密集型任务的多线程。

weixin_42914989的博客 1525

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Python中的并发与并行

本文介绍Python中的并发与并行

诸神缄默不语的博客 1073

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Python基础:并行与并发概念

总的来说,Python多线程实质上是并发,其受限于GIL的存在。 但Python可以通过asyncio或Multiprocessing绕过GIL。也可以通过 C/C++(如 Cython)或 Rust 编写扩展模块。这些模块在执行时不受 GIL 限制,可以充分利用多核并行计算。许多高性能的 AI 库(如 NumPy、TensorFlow、PyTorch)底层就是用 C/C++ 优化的。

啾啾头号大粉丝打工买粮博客 1056

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

python之并发和并行

并发(concurrency)和它的表现形式之一并行处理(parallel processing)是就计算机领域开发过程中经常讨论的话题之一。今天,博主就谈谈自己对这两个名次的理解吧! 并发概念: 在1976年Leslie Lamportfa发表的论文中指出了。如果说两个事件互相不影响,则两个事件是并发的。通过推断程序,算法或者问题中事件,我们可以说,如果他们可以完全或者部分分解为顺序无关的组件单...

菜鸡小白的成长记录 2870

Python并发与并行

简明介绍 Python 多线程 多进程的基本使用

白切鸡 PYTHON 1769

python 并发 并行

死锁产生的前三个条件是死锁产生的必要条件,也就是说要产生死锁必须具备的条件,而不是存在这3个条件就一定产生死锁,那么只要在逻辑上回避了第四个条件就可以避免死锁。避免死锁采用的是允许前三个条件存在,但通过合理的资源分配算法来确保永远不会形成环形等待的封闭进程链,从而避免死锁。该方法支持多个进程的并行执行,为了避免死锁,系统动态的确定是否分配一个资源给请求的进程。如果会死锁,则不分配,否则就分配。要求每个进程必须先知道资源的最大需求量,且在系统运行过程中,考察每个进程对各类资源的申请需要花费较多的时间。

EveyD的博客 925

python多线程是并发还是并行_python_并行与并发、多线程

问题一: 计算机是如何执行程序指令的? 问题二: 计算机如何实现并发的?轮询调度实现并发执行 程序1-8轮询完成,才再CPU上运行 问题三: 真正的并行需要依赖什么?并行需要的核心条件 多进程实现并行问题一: 什么是进程?计算机程序是存储在磁盘上的文件。只有把它们加载到内存中,并被操作系统调用 它们才会拥有其自己的生命周期。进程表示一个正在执行的程序。每个进程都有独立地址空间以及其他的辅助数据进程...

weixin_33603844的博客 1679

【Python爬虫4】并发并行下载

1一百万个网站 1用普通方法解析Alexa列表 2复用爬虫代码解析Alexa列表 2串行爬虫 3并发并行爬虫 0并发并行工作原理 1多线程爬虫 2多进程爬虫 4性能对比这篇将介绍使用多线程和多进程这两种方式并发并行下载网页,并将它们与串行下载的性能进行比较。1一百万个网站亚马逊子公司Alexa提供了最受欢迎的100万个网站列表(http://www.alexa.com/topsites ),我们也可

Wu_Being 的优快云 博客 9591

并发和并行

并发与并行代表了不同的“同时性”实现方式:并发是时间维度上的复用,并行是空间维度上的分配。在系统设计中,应根据任务特征与资源环境,灵活运用二者,以实现高效、可靠的并发处理和大规模计算能力。在高性能与高可用系统设计中,“并发”(Concurrency)与“并行”(Parallelism)是两个常被提及但容易混淆的概念。可以看到,同样是 3 个 CPU 密集型任务,串行执行总耗时约 9 秒,而在 3 核心并行时总耗时约 3 秒。可见,3 个 I/O 任务在。模式下总耗时约 3 秒,而在。

chen的博客 2204

详解并发和并行意义

很多人不是特别明白并发编程和并行编程的区别所在,有很多人很容易搞混淆,觉得二者近似相等,本文将用几个浅显易懂的例子,来说明一下什么是并发和并行。 1、任务与多任务        关于什么是进程,什么是线程,这里不打算多说,关于每一种开发语言的多线程处理技术语法上有所区别,原理很多类似,可以查阅相关的参考书。什么是任务呢?其实很简单,在我们生活中,比如我今天要学一首歌,要在操场上散步1000米,

MIss-Y的博客 3万+
上一篇: python爬取拉勾网数据并进行数据可视化!
下一篇: 3分钟看懂Python面向对象!
普通网友
博客等级 码龄7年 438粉丝 263原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值