【python】并发编程——多进程

Python 多线程与多进程:解锁并发编程的高效之道 并发编程是指在同一时间段内处理多个任务,通常是通过分配多个任务在多个执行单元(线程或进程)上执行。并发并不意味着任务同时进行,而是通过时间分片或上下文切换实现多任务的交替执行。多线程:在单个进程内运行多个线程,每个线程独立执行任务。多进程:启动多个独立的进程,每个进程有独立的内存空间。在 Python 中,由于全局解释器锁(GIL),多线程的并发性能在 CPU 密集型任务中受到了很大限制。因此,针对不同类型的任务,开发者需要选择合适的并发模型。多线程。 阅读详情

1 一些概念

1.1 并行与并发

并发concurrency

并发指计算机同时管理多个和任务的能力。这些任务并不要求在每时每刻同时执行,但是可能在一段时间内交错执行。并发的任务是处理多个用户输入,管理多个I/O任务,或者处理多个独立任务。并发适合依赖诸如文件和网络数据等外部资源的I/O约束型的操作。

并行parallelism

并行是并发的子集。并发要求多个任务每时每刻同时执行。并行的任务是提升计算效率和加速系统性能。并行需要利用多核CPU特性,适合CPU密集型任务。

concurrency in Python

并发类型

  • processed-based concurrency:multiprocessing
  • thread-based concurrency:threading
  • coroutine-based concurrency:async/await关键字

补充:python提供concurent.future库来提供进程/线程并发

1.2 多处理器系统

多核系统:CPU芯片上集成多个核心,结构上可以是对称多处理SMP(所有核心地位相同)和非对称处理(核心有主从之分)。
集群系统:两个或者多个独立系统通过计算机网络组成。将应用程序的不同部分并行运行在集群的不同系统上的技术称为并行计算技术。集群系统结构上可以是对称或者非对称的。

1.3 CPU,物理核心,逻辑核心,超线程

CPU:中央处理器,一个CPU芯片可以集成多个CPU核心。
CPU物理核心:有独立的电路,L1,L2高速缓存,能独立执行指令。
CPU逻辑核心:应用程序将一个高速运转的CPU物理核心看做一个或者多个核心,应用程序视角下的核心就是逻辑核心。如果一个物理核心对应两个逻辑核心,意味着CPU采用了超线程技术。逻辑CPU数量=同时可执行的线程数。
超线程:超线程可以在一个逻辑核等待指令执行的间隔(等待从cache或内存中获取下一条指令),把时间片分配到另一个逻辑核。CPU在这两个逻辑核之间高速切换,让应用程序感知不到这个间隔,误认为自己是独占了一个核。实现超线程需要在CPU物理核心内设置冗余部件,才能让多个线程运行在一个物理核心上,从而实现一个物理核心对应多个逻辑核心。
在这里插入图片描述

# mac
# 查看CPU型号
sysctl machdep.cpu.brand_string
# 查看CPU物理核心数
sysctl hw.physicalcpu
# 查看CPU逻辑核心数
sysctl hw.logicalcpu

# linux
# 查看CPU型号
cat /proc/cpuinfo | grep "model name"
# 查看CPU物理核心数
~$ lscpu -p | egrep -v '^#' | wc -l
# 查看CPU逻辑核心数
~$ lscpu -p | egrep -v '^#' | sort -u -t, -k 2,4 | wc -l

2 Python多进程

python多线程无法利用多核优势,在执行并发任务需要使用多进程来完成

2.1 进程池

2.1.1 阻塞调用方式

调用进程会在执行p.map()时阻塞,直到所有任务执行完毕返回结果。p.map()返回的结果列表顺序和参数列表顺序一致。p.imap_unordered()返回的结果列表顺序和参数列表顺序不一致。

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    with Pool(5) as p:
        print(p.map(f, [1, 2, 3]))  # [1, 4, 9]
        print(p.imap_unordered(f, range(10)))  # arbitrary order
# 数据并行:将数据分成多个部分,分配给多个进程执行

2.1.2 非阻塞调用方式

方式一:使用apply_async
from multiprocessing import Pool, TimeoutError
import time
import os

def f(x):
    return x*x

if __name__ == '__main__':
    # start 4 worker processes
    with Pool(processes=4) as pool:
        # evaluate "f(20)" asynchronously
        res = pool.apply_async(f, (20,))      # runs in *only* one process
        print(res.get(timeout=1))             # prints "400"

        # evaluate "os.getpid()" asynchronously
        res = pool.apply_async(os.getpid, ()) # runs in *only* one process
        print(res.get(timeout=1))             # prints the PID of that process

        # launching multiple evaluations asynchronously *may* use more processes
        multiple_results = [pool.apply_async(os.getpid, ()) for i in range(4)]
        print([res.get(timeout=1) for res in multiple_results])

        # make a single worker sleep for 10 seconds
        res = pool.apply_async(time.sleep, (10,))
        try:
            print(res.get(timeout=1))
        except TimeoutError:
            print("We lacked patience and got a multiprocessing.TimeoutError")

        print("For the moment, the pool remains available for more work")

    # exiting the 'with'-block has stopped the pool
    print("Now the pool is closed and no longer available")
方式二:使用concurrent.futures
import concurrent.futures
import math

PRIMES = [
    112272535095293,
    112582705942171
]

def is_prime(n):
    pass

def main():
    with concurrent.futures.ProcessPoolExecutor() as executor:
        for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):
            print('%d is prime: %s' % (number, prime))

if __name__ == '__main__':
    main()

2.1.3 补充

Python built-in apply
apply(function, args=None, kwargs=None)

def f1(a, b=0, c=0):
    return a + b + c
def f2(name, age):
    return name + ': ' + str(age)

ret = apply(f1, (1), {'b': 2, 'c': 3})           # ret=6,传递的实参为a=1, b=2, c=3
ret = apply(f2, (), {'name': 'aa', 'age': 12})  # ret='aa: 12'
ret = apply(f2, ('bb'), {'age': 12})            # ret='bb: 12'
Python built-in map

map(function, iterable, *iterables):返回一个迭代器生成用iterable的每一项作为参数调用function而得到的结果。如果function需要n个参数,则后续需要传入n个iterable

list(map(lambda x: 2**x, [1, 2, 3, 4, 5, 6, 8]))  # [2, 4, 8, 16, 32, 64, 256]

first_it = [1, 2, 3]
second_it = [4, 5, 6, 7]
list(map(pow, first_it, second_it))  # [1, 32, 729]
什么时候使用map,apply,apply_async
  • ret_list = concurrent.futures.ProcessPoolExecutor().map(func, [p1, p2, …])本身不阻塞,ret_list为迭代对象,在迭代ret_list时,可能会阻塞,因为结果列表和参数列表保持一致的,如果第i个进程没有执行完毕,则迭代会阻塞在第i个结果元素上。
  • Pool.async_apply()调用完立刻返回一个AsyncResuult对象。可以调用AsyncResuult对象的get()来获取调用结果。get()将会阻塞直到func执行结束。
  • Pool.apply((func, args, kwargs))将会阻塞直到func执行完毕,Pool.apply(func, args, kwargs) 等价于Pool.apply_async(func, args, kwargs, callback, error_callback).get()。Pool.apply_async有callback,一旦func执行完毕,callback开始执行,因此也可通过callback获取func执行的结果。
import multiprocessing as mp
import time

def foo_pool(x):
    time.sleep(2)
    return x*x

result_list = []
def log_result(result):
    # This is called whenever foo_pool(i) returns a result.
    # result_list is modified only by the main process, not the pool workers.
    result_list.append(result)

def apply_async_with_callback():
    pool = mp.Pool()
    for i in range(10):
        pool.apply_async(foo_pool, args = (i, ), callback = log_result)
    pool.close()  # 阻止任何任务向pool提交
    pool.join()   # 阻塞直到所有工作进程退出,执行join前必须先执行close
    print(result_list)

if __name__ == '__main__':
    apply_async_with_callback()

2.2 Process对象

2.2.1 使用方式

# 直接使用
from multiprocessing import Process

def f(name):
    print('hello', name)

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    p.join() # 阻塞直到p执行完毕

# 继承使用
import time
import random
from multiprocessing import Process

class Run(Process):
    def __init__(self,name):
        super().__init__()
        self.name=name
    def run(self):
        print('%s runing' %self.name)
        time.sleep(random.randrange(1,5))
        print('%s runing end' %self.name)

if __name__ == '__main__':
    p1=Run('anne')
    p2=Run('alex')
    p1.start() #start会自动调用run
    p2.start()
    p1.join()
    p2.join()
    print('主线程')

2.2.2 start method

创建子进程的三种方式

• spawn: 创建一个新的解释器进程,仅仅继承足以支持进程对象执行run()的资源,不继承不必要的资源(内存、文件描述符、线程等),相比于fork方式速度很慢。每个子进程都有全新的状态。(fork() & execv())。
• fork: 对父进程虚拟内存(已初始化的Python解释器、已加载的模块,内存中的对象)进行写时复制,但不复制父进程的线程。父进程所有资源被子进程继承,子进程维护一份父进程状态副本。
• forkserver: 父进程spawn一个服务进程(fork server),如果父进程需要创建子进程,用这个服务进程来fork()子进程。

platform support

• Windows (win32): spawn(default)
• macOS (darwin): spawn(default), fork, forkserver.
• Linux (unix): spawn, fork(default), forkserver.

2.2.3 IPC

IPC有共享内存和消息机制两种类型,服务器/客户端系统还可以通过socket,管道,RPC进行通信,此处不展开。shared memory和server process两节中的例程展现的共享存储方式属于基于数据结构的共享(低级方式),而非基于存储区的共享(高级方式)。

队列

队列是线程安全或者进程安全(不需要程序员考虑临界区问题),对象被放入队列时会被序列化。

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
管道

全双工,不同进程使用同时同一端读取或者写入数据,则数据可能被破坏,因此可能多个进程需要互斥使用管道同一端。2个不同进程同时使用管道不同端,不会破坏数据。parent_conn和child_conn代表管道的两端。都可以调用send()和recv()。调用send()将序列化对象,调用recv()将恢复对象。

from multiprocessing import Process, Pipe

def f(conn):
    conn.send([42, None, 'hello'])
    conn.close()

if __name__ == '__main__':
    parent_conn, child_conn = Pipe()
    p = Process(target=f, args=(child_conn,))
    p.start()
    print(parent_conn.recv())   # prints "[42, None, 'hello']"
    p.join()
shared memory

shared memory用于进程之间共享状态。应该尽可能避免进程之间共享状态。multiprocessing提供基于数据结构的内存共享方式(Value,Array)而非基于存储区的共享方式。这些共享对象将是进程和线程安全的(不需要程序员考虑临界区问题)。

from multiprocessing import Process, Value, Array

def f(n, a):
    n.value = 3.1415927
    for i in range(len(a)):
        a[i] = -a[i]

if __name__ == '__main__':
    num = Value('d', 0.0)
    arr = Array('i', range(10))

    p = Process(target=f, args=(num, arr))
    p.start()
    p.join()

    print(num.value)  # 3.1415927
    print(arr[:])  # [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
server process

server process用于进程之间共享状态。也是基于数据结构的内存共享方式。相比于使用shared memory objects,使用server process manager更灵活,因为manager对象提供更多类型,不过速度也更慢。
manager对象对应一个本地或远程的服务进程,调用manager.dict()则令服务进程创建dict对象并返回这个共享对象的代理,然后协作的进程可以通过代理访问此共享对象。
server process支持的共享对象类型:list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value and Array。

from multiprocessing import Process, Manager

def f(d, l):
    d[1] = '1'
    d['2'] = 2
    d[0.25] = None
    l.reverse()

if __name__ == '__main__':
    with Manager() as manager:
        d = manager.dict()
        l = manager.list(range(10))

        p = Process(target=f, args=(d, l))
        p.start()
        p.join()

        print(d)  # {0.25: None, 1: '1', '2': 2}
        print(l)  # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

2.2.4 进程同步关系(加锁,释放锁)

from multiprocessing import Process, Lock

def f(l, i):
    l.acquire()
    try:
        print('hello world', i)
    finally:
        l.release()

if __name__ == '__main__':
    lock = Lock()

    for num in range(10):
        Process(target=f, args=(lock, num)).start()

2.3 subprocess

通常用于启动外部进程。

import subprocess

def main():
    print("启动外部进程")
    subprocess.run(["ls", "-l"])
    print("外部进程执行完毕")

if __name__ == "__main__":
    main()

3 参考

https://www.geeksforgeeks.org/python-program-with-concurrency/
https://python-parallel-programmning-cookbook.readthedocs.io/zh-cn/latest/chapter1/index.html
IPC: https://www.geeksforgeeks.org/python-subprocess-module/

Python并发编程实践:asyncio与多进程深度解析 在单核处理器时代,程序性能提升主要依赖时钟频率的提升。但随着摩尔定律逐渐失效(2005年后CPU主频增长停滞),单核性能提升空间收窄至每年约3%。结构化并发:引入类似Trio的nursery概念,确保所有子任务在父任务退出前完成。分布式任务队列:集成Celery与asyncio,支持跨节点任务分发。跨语言互操作:通过PyO3与Rust集成,提升异步任务性能。性能优化:asyncio核心性能提升40%适用场景:GUI事件处理、轻量级IO任务。优势:超高并发密度(可管理10K+任务) 阅读详情

相关推荐

python并发编程多进程 互斥锁原理解析

这篇文章主要介绍了python并发编程多进程 互斥锁原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 运行多进程 每个子进程的内存空间是互相隔离的 进程之间数据不能共享的 互斥锁 但是进程之间都是运行在一个操作系统上,进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端, 是可以的,而共享带来的是竞争,竞争带来的...

python编程基础教程 1411

Python多进程编程

一 多进程编程Python实现多进程的方式有两种:一种方法是os模块中的fork方法,另一种是使用multiprocessing模块。前者仅适用于LINUX/UNIX操作系统,对Windows不支持,后者则是跨平台的实现方式。第一种方式:使用os模块中的fork方式实现多进程第二种方式:multiprocessing由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。

m0_59485658的博客 2013

python并发编程(多进程)

目录: 操作系统发展 进程理论 创建进程的两种方式 join方法 操作系统发展 多道技术 1.空间上的复用 多个程序公用一套计算机硬件 2.时间上的复用 cpu会在多个程序之间来回切换 1.程序遇到IO主动切 2.程序长时间(时间片)占用CPU切 切换 + 保存状态 回到目录 进程理论 进程与程序的区别: 程序:一堆死代码 进程:正在运行的程序 进程...

番茄炒蛋君的博客 525

Python-多进程编程 (multiprocessing 模块)

本文对 Python 的 multiprocessing 模块进行归纳总结,该模块支持多核并行处理,可以提升程序效率。

kusunoki的博客 3114

Python的多线程与多进程:并发编程基础与实战

本文详细介绍了Python中的并发编程,涵盖多线程、多进程和异步编程(asyncio)的基本原理和应用场景。文章分析了各技术的优势和局限,并通过代码示例展示了如何使用threading、multiprocessing和asyncio模块实现并发操作。结合表格对比了这些技术在I/O密集型和CPU密集型任务中的适用场景,帮助读者理解如何在不同需求下选择合适的并发编程方法,以提升程序的性能和效率。

一个被知识诅咒的人 1466

Python:实现并发任务 (含完整源代码)

在Python中,可以通过threading模块创建并启动多个线程,这些线程可以同时运行,从而实现并发处理任务。完整的源代码已经提供,在此不再赘述。可以看到,由于这些线程并行运行,因此每个任务之间的等待时间可以重叠,从而缩短了总处理时间。需要注意的是,在异步编程中,需要注意协程之间的顺序、并发性等问题,以避免出现意外的结果。需要注意的是,在多线程编程中,需要注意锁、同步等问题,以避免出现数据竞争、死锁等问题。可以看到,由于使用了异步编程的特性,这些协程之间不会互相阻塞,从而实现了并发运行。

持续更新 276

Python并发编程——多进程

在上篇文章我们学习了,这篇我们学习Python并发编程——多进程。

霖hero 850

Python 并发编程:多进程、多线程、GIL 锁与 ThreadLocal一览

Python 并发编程:多进程、多线程、GIL 锁与 ThreadLocal一览

孤寒者的博客 1万+

python并发编程之多进程

ptthon并发编程之多进程 ​ 在讲解python多进程之前,我们先引出一个话题,什么话题呢?“多任务”,那么什么是多任务呢,它是干什么的呢,来让我们一起来看看吧! 一、多任务 1、什么是多任务? ​ (1)在python中所了解到的函数执行,遇到多个函数调用,它的执行方式是按照函数调用的顺序依次挨个执行,基本上不可能出现多个函数同时执行的现象。 ​ (2)那么,也就是说我们所写的程序都是但任务的,一个函数或者方法执行完毕,另一个函数或者方法才能正常执行。如果想要多个函数或方法同时调用执行,需要使用

abraham_ly的博客 388

PCAN-Explorer5使用教程

在PCAN中新建工程,导入DBC文件(右键apply),导入采集的数据选择对应的CAN通道点击红框中的标记可选择想要查看的信号在plot界面跳出属性,可调整信号显示的样式和最大最小值调出cursor,选择需要观测的变量,选中右键style——Period 可显示间隔时间增加cursor,可观测多个变量。

weixin_43997043的博客 6913

Win10自动更新怎么永久关闭?有效的Win10强制更新关闭方法

之前小编为大家分享过一些Win10彻底关闭Windows Update自动更新的方法,主要是通过一些如设置流量计费或借助一些专门的小工具来实现,但往往会发现,Win10自动更新就像打不死的小强,不管怎么关闭,之后还是会自动更新,让不少小伙伴颇为不爽。今天小编带来了这篇改进型教程,通过全方位设置,彻底关闭Win10自动更新,感兴趣的小伙伴不妨试试吧。 ...

jianai0602的博客 108万+

FPGA入门必做:可逆计数器设计详解与上板调试

在FPGA数字逻辑设计中,时序逻辑是核心基础,而计数器作为最典型的时序电路,是理解时钟、复位和状态跳转的关键。可逆计数器通过方向控制实现加减计数,涉及信号同步、位宽选择和溢出处理等通用技术。掌握这些原理不仅能提升代码稳定性,还能有效避免亚稳态和竞争冒险。其技术价值在于以最小资源消耗验证时序约束和仿真验证流程,广泛应用于分频、定时和位置控制等场景。本文以可逆计数器为例,从设计思路到上板调试,帮助初学者打牢时序逻辑基本功。

weixin_30235225的博客 283

Arxml文件可视化:当汽车软件架构遇见交互式设计工具

本文探讨了Arxml文件在汽车电子系统开发中的可视化技术,结合AUTOSAR架构标准,介绍了如何利用现代Web技术构建交互式设计工具。通过三维组件关系图、动态数据流展示和版本对比等功能,显著提升开发效率和架构评审质量,适用于MBD和ASPICE开发流程。

weixin_29050271的博客 428

深入浅出Python多线程、多进程和并发编程

并发编程是解决现代计算机应用中性能瓶颈的重要工具,本文的目的是帮助你掌握这一强大技术,让你能够更好地应对多任务、高并发的编程需求。通过开发这两个通用函数模板,用户可以在自己的项目中轻松使用多线程和多进程,只需编写具体的任务函数并传入合适的线程数量或进程数量,即可快速实现并发处理,提高程序的性能和效率。这个并发通用函数模板允许用户同时使用多线程和多进程,根据实际情况选择合适的线程数量和进程数量,充分利用硬件资源,提高程序的性能。一个常见的方法是使用细粒度的锁,以减少锁的粒度,只保护必要的资源。

u013112984的博客 1406

打通Creo与Matlab的桥梁:Simscape Multibody Link插件安装与配置全攻略

本文详细介绍了Simscape Multibody Link插件的安装与配置全流程,旨在帮助机械工程师和开发者打通Creo与Matlab/Simulink之间的桥梁,实现CAD模型到多体动力学仿真的高效转换。文章重点解析了版本兼容性、管理员权限、注册文件配置等关键步骤与常见故障排查方法,助力用户快速建立设计与仿真一体化工作流。

rrr55的博客 634

Vivado项目开发新思路:用VSCode写代码,用Vivado管理IP核与综合(Windows/Mac环境通用指南)

本文介绍了如何结合Vivado和VSCode的优势,打造高效的FPGA设计工作流。通过配置VSCode的Verilog插件和Vivado环境集成,开发者可以在VSCode中编写代码,同时利用Vivado管理IP核与综合,显著提升开发效率和团队协作体验。

weixin_42545503的博客 337

Python并发编程:多进程

并发编程指的是在一个程序中同时执行多个独立的任务(或操作),使得这些任务看起来是同时执行的。并发编程有多种实现方式,这里仅介绍多线程和多进程。模块中,通常使用消息传递机制进行进程之间的通信(尽量避免使用锁这类同步原语)。

读万卷书 行万里路 732

YOLOv12改进策略【Neck】| 使用CARAFE轻量级通用上采样算子

CARAFE内容感知的特征重新组合。

Limiiiing的博客 664

python多进程关闭socket_Python并发编程-多进程socketserver简易版

普通版的socketserver#server.pyimport socketsk = socket.socket()sk.bind(('127.0.0.1',8080))#建立连接sk.listen() #打开监听while True:conn,addr = sk.accept() #接收到一个连接和一个地址ret = 'hi'.encode('utf-8')conn.send(ret)msg ...

weixin_39783915的博客 486

学Simulink——基于Simulink的Buck-Boost变换器双闭环PI+抗饱和设计建模示例

本文详细介绍了基于Simulink的非反相Buck-Boost变换器双闭环控制设计方法。针对Buck-Boost变换器特有的右半平面零点(RHPZ)和控制挑战,提出了电压-电流双闭环PI控制架构,并集成抗积分饱和机制。通过Simulink建模,实现了主电路、电流内环PI、电压外环PI、PWM及占空比限幅等模块的搭建,验证了在输入电压跌落(20V→10V)和负载突变(2A→4A)等场景下的稳定性能。仿真结果表明,输出电压波动小于0.35V,恢复时间快于1ms,电感电流有效限幅。文章还讨论了工程实践要点和扩展方

xiaoheshang_123的博客 318

uniapp - 实现苹果App打包上架App Store应用商店详细教程,详解Hbuilder打包编译ipa发布上传到苹果ios软件商店全流程,提供云打包/离线本地打包ios、申请IOS苹果证书方法

uni-app,苹果ios,苹果app,打包编译,appstore应用商店,ipa发布到软件商店,uniapp的app苹果应用商店上架,上架苹果APPStore,uniApp打包的ipa文件上传到商店,上架苹果商城,审核失败,被拒绝,UniApp打包ipa文件,上架iOSAppStore流程指南,最新详细教程最全,Hbuilder打包发布iosapp,苹果云打包上线全过程,云打包IPA并上传到商店,打包iOSipa文件后怎么发布到应用商店,苹果证书申请教程,ios证书申请,mac电脑,审核很久

🏆 前端领域优质创作者 1万+

【Python并发编程】多线程与多进程,提升程序性能!

并发编程是指通过让程序的多个部分同时执行,来提升效率和性能的技术。在传统的单线程程序中,任务按顺序执行,这意味着一个任务的执行会阻塞其他任务。而并发编程允许任务在同一时间段内“并行”或“交替”执行,以提高程序的响应速度。多线程(multithreading):在同一个进程中创建多个线程,线程共享相同的内存空间。多进程(multiprocessing):通过创建多个进程,每个进程有自己独立的内存空间。通过本文的学习,我们了解了 Python 并发编程中的两个关键概念——多线程和多进程。

萧鼎的博客 1375

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Python并发编程:多线程与多进程实践

并发编程是指计算机系统中同时执行多个独立的计算任务。这些任务可以同时执行也可以按照一定的调度策略交替执行。在并发编程中执行的任务需要独立管理自身的资源,且需要与其他任务共享资源。Python提供了threading模块用于创建和管理多个线程。上述代码创建了两个线程分别执行worker()函数。使用start()函数启动线程,使用join()函数等待线程执行完毕。

BXA 1229

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

python多进程并发代码_python并发编程之多进程

一 multiprocessing模块介绍python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程。Python提供了multiprocessing。multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似。mult...

weixin_39840606的博客 199
上一篇: 【python】正则表达式
下一篇: 【python】并发编程——多线程
南隅。
博客等级 码龄8年 279粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值