python基础之并发编程(二)

目录
  • 一、多进程的实现
    • 方法一
    • 方法二:
  • 二、使用进程的优缺点
    • 1、优点
    • 2、缺点
  • 三、进程的通信
    • 1、Queue 实现进程间通信
    • 2、Pipe 实现进程间通信(一边发送send(obj),一边接收(obj))
  • 四、Manager管理器
  • 五、进程池
  • 总结

一、多进程的实现

方法一

# 方法包装   多进程
from multiprocessing import Process
from time import sleep
def func1(arg):
    print(f'{arg}开始...')
    sleep(2)
    print(f'{arg}结束...')
if __name__ == "__main__":
    p1 = Process(target=func1,args=('p1',))
    p2 = Process(target=func1,args=('p2',))
    p1.start()
    p2.start()

方法二:

二、使用进程的优缺点

1、优点

  • 可以使用计算机多核,进行任务的并发执行,提高执行效率
  • 运行不受其他进程影响,创建方便
  • 空间独立,数据安全

2、缺点

  • 进程的创建和删除消耗的系统资源较多

三、进程的通信

Python 提供了多种实现进程间通信的机制,主要有以下 2 种:

1. Python multiprocessing 模块下的 Queue 类,提供了多个进程之间实现通信的诸多 方法

2. Pipe,又被称为“管道”,常用于实现 2 个进程之间的通信,这 2 个进程分别位于管 道的两端

Pipe 直译过来的意思是“管”或“管道”,该种实现多进程编程的方式,和实际生活中 的管(管道)是非常类似的。通常情况下,管道有 2 个口,而 Pipe 也常用来实现 2 个进程之 间的通信,这 2 个进程分别位于管道的两端,一端用来发送数据,另一端用来接收数据 - send(obj)

发送一个 obj 给管道的另一端,另一端使用 recv() 方法接收。需要说明的是,该 obj 必 须是可序列化的,如果该对象序列化之后超过 32MB,则很可能会引发 ValueError 异常 - recv()

接收另一端通过 send() 方法发送过来的数据 - close()

关闭连接 - poll([timeout])

返回连接中是否还有数据可以读取 - end_bytes(buffer[, offset[, size]])

发送字节数据。如果没有指定 offset、size 参数,则默认发送 buffer 字节串的全部数 据;如果指定了 offset 和 size 参数,则只发送 buffer 字节串中从 offset 开始、长度为 size 的字节数据。通过该方法发送的数据,应该使用 recv_bytes() 或 recv_bytes_into 方法接收 - recv_bytes([maxlength])

接收通过 send_bytes() 方法发送的数据,maxlength 指定最多接收的字节数。该方法返 回接收到的字节数据 - recv_bytes_into(buffer[, offset])

功能与 recv_bytes() 方法类似,只是该方法将接收到的数据放在 buffer 中

1、Queue 实现进程间通信

from multiprocessing import Process,current_process,Queue   # current_process 指的是当前进程
# from queue import Queue
import os
def func(name,mq):
    print('进程ID {} 获取了数据:{}'.format(os.getpid(),mq.get()))
    mq.put('shiyi')
if __name__ == "__main__":
    # print('进程ID:{}'.format(current_process().pid))
    # print('进程ID:{}'.format(os.getpid()))
    mq = Queue()
    mq.put('yangyang')
    p1 = Process(target=func,args=('p1',mq))
    p1.start()
    p1.join()
    print(mq.get())

2、Pipe 实现进程间通信(一边发送send(obj),一边接收(obj))

from multiprocessing import Process,current_process,Pipe
import os
def func(name,con):
    print('进程ID {} 获取了数据:{}'.format(os.getpid(),con.recv()))
    con.send('你好!')
if __name__ == "__main__":
    # print('进程ID:{}'.format(current_process().pid))
    con1,con2 = Pipe()
    p1 = Process(target=func,args=('p1',con1))
    p1.start()
    con2.send("hello!")
    p1.join()
    print(con2.recv())

四、Manager管理器

管理器提供了一种创建共享数据的方法,从而可以在不同进程中共享

from multiprocessing import Process,current_process
import os
from multiprocessing import Manager
def func(name,m_list,m_dict):
    print('子进程ID {} 获取了数据:{}'.format(os.getpid(),m_list))
    print('子进程ID {} 获取了数据:{}'.format(os.getpid(),m_dict))
    m_list.append('你好')
    m_dict['name'] = 'shiyi'
if __name__ == "__main__":
    print('主进程ID:{}'.format(current_process().pid))
    with Manager() as mgr:
        m_list = mgr.list()
        m_dict = mgr.dict()
        m_list.append('Hello!!')
        p1 = Process(target=func,args=('p1',m_list,m_dict))
        p1.start()
        p1.join()
        print(m_list)
        print(m_dict)

五、进程池

Python 提供了更好的管理多个进程的方式,就是使用进程池。

进程池可以提供指定数量的进程给用户使用,即当有新的请求提交到进程池中时,如果池 未满,则会创建一个新的进程用来执行该请求;反之,如果池中的进程数已经达到规定最大 值,那么该请求就会等待,只要池中有进程空闲下来,该请求就能得到执行。

使用进程池的优点

1. 提高效率,节省开辟进程和开辟内存空间的时间及销毁进程的时间

2. 节省内存空间

类/方法 功能 参数

Pool(processes)

创建进程池对象

processes 表示进程池

中有多少进程


pool.apply_async(func,a

rgs,kwds)


异步执行 ;将事件放入到进 程池队列


func 事件函数

args 以元组形式给

func 传参

kwds 以字典形式给

func 传参 返回值:返

回一个代表进程池事件的对

象,通过返回值的 get 方法

可以得到事件函数的返回值


pool.apply(func,args,kw

ds)


同步执行;将事件放入到进程 池队列


func 事件函数 args 以

元组形式给 func 传参

kwds 以字典形式给 func

传参


pool.close()

关闭进程池

pool.join()

回收进程池

pool.map(func,iter)

类似于 python 的 map 函

数,将要做的事件放入进程池


func 要执行的函数

iter 迭代对象

from multiprocessing import Pool
import os
from time import sleep
def func1(name):
    print(f"当前进程的ID:{os.getpid()},{name}")
    sleep(2)
    return name
def func2(args):
    print(args)
if __name__ == "__main__":
    pool = Pool(5)
    pool.apply_async(func = func1,args=('t1',),callback=func2)
    pool.apply_async(func = func1,args=('t2',),callback=func2)
    pool.apply_async(func = func1,args=('t3',),callback=func2)
    pool.apply_async(func = func1,args=('t4',))
    pool.apply_async(func = func1,args=('t5',))
    pool.apply_async(func = func1,args=('t6',))
    pool.close()
    pool.join()
from multiprocessing import Pool
import os
from time import sleep
def func1(name):
    print(f"当前进程的ID:{os.getpid()},{name}")
    sleep(2)
    return name
if __name__ == "__main__":
   with Pool(5) as pool:
        args = pool.map(func1,('t1,','t2,','t3,','t4,','t5,','t6,','t7,','t8,'))
        for a in args:
            print(a)

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • python基础之并发编程(三)

    目录 一.协程定义和作用 1.使用协程的优点 2.使用协程的缺点 二.Greenlet 的使用 三.Gevent的使用 四.async io 异步 IO 1.asyncio中的task的使用 五.总结 进程与线程的区别: 进程.线程和协程的特点 总结 一.协程定义和作用 协程(coroutine),又称为微线程,纤程.(协程是一种用户态的轻量级线程) 作用:在执行 A 函数的时候,可以随时中断,去执行 B 函数,然后中断继续执行 A 函数 (可以自动切换),单着一过程并不是函数调用(没有调用语句

  • python基础之并发编程(一)

    目录 一.进程(Process) 二.线程(Thread) 三.并发编程解决方案: 四.多线程实现 (两种) 1.第一种 函数方法 2.第二种 类方法包装 五.守护线程与子线程 1.线程在分法有: 2.守护线程 六.锁 七.死锁 八.信号量(Semaphore) 九.事件(Event) 十.线程通信-队列 1使用的队列的好处: 2Queue模块中的常用方法: 十一.生产者和消费者模式 总结 一.进程(Process) 是一个具有一定独立功能的程序关于某个数据集合的一次运行活动 二.线程(Thre

  • 理论讲解python多进程并发编程

    一.什么是进程 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu. 二.进程与程序的区别 程序:仅仅是一堆代 进程:是指打开程序运行的过程 三.并发与并行 并发与并行是指cpu运行多个程序的方式 不管是并行与并发,在用户看起来都是'同时'运行的,他们都只是一个任务而已,正在干活的是cpu,而一个cpu只能执行一个任务. 并行就相当于有好多台设备,可以同时供好多人使用. 而并发就相当于只有一台设备,供几个人轮流用,每个人用一会就换另一个人. 所以只有多个cpu才能实现并行,而一个c

  • Python并发编程线程消息通信机制详解

    目录 1 Event事件 2 Condition 3 Queue队列 4 总结一下 前面我已经向大家介绍了,如何使用创建线程,启动线程.相信大家都会有这样一个想法,线程无非就是创建一下,然后再start()下,实在是太简单了. 可是要知道,在真实的项目中,实际场景可要我们举的例子要复杂的多得多,不同线程的执行可能是有顺序的,或者说他们的执行是有条件的,是要受控制的.如果仅仅依靠前面学的那点浅薄的知识,是远远不够的. 那今天,我们就来探讨一下如何控制线程的触发执行. 要实现对多个线程进行控制,其实

  • python并发编程之线程实例解析

    常用用法 t.is_alive() Python中线程会在一个单独的系统级别线程中执行(比如一个POSIX线程或者一个Windows线程) 这些线程将由操作系统来全权管理.线程一旦启动,将独立执行直到目标函数返回.可以通过查询 一个线程对象的状态,看它是否还在执行t.is_alive() t.join() 可以把一个线程加入到当前线程,并等待它终止 Python解释器在所有线程都终止后才继续执行代码剩余的部分 daemon 对于需要长时间运行的线程或者需要一直运行的后台任务,可以用后台线程(也称

  • python基础之并发编程(二)

    目录 一.多进程的实现 方法一 方法二: 二.使用进程的优缺点 1.优点 2.缺点 三.进程的通信 1.Queue 实现进程间通信 2.Pipe 实现进程间通信(一边发送send(obj),一边接收(obj)) 四.Manager管理器 五.进程池 总结 一.多进程的实现 方法一 # 方法包装 多进程 from multiprocessing import Process from time import sleep def func1(arg): print(f'{arg}开始...') sl

  • Python基础之元编程知识总结

    一.前言 首先说,Python中一切皆对象,老生常谈.还有,Python提供了许多特殊方法.元类等等这样的"元编程"机制.像给对象动态添加属性方法之类的,在Python中根本谈不上是"元编程",但在某些静态语言中却是需要一定技巧的东西.我们来谈些Python程序员也容易被搞糊涂的东西. 我们先来把对象分分层次,通常我们知道一个对象有它的类型,老早以前Python就将类型也实现为对象.这样我们就有了实例对象和类对象.这是两个层次.稍有基础的读者就会知道还有元类这个东西

  • Python中的并发编程实例

    一.简介 我们将一个正在运行的程序称为进程.每个进程都有它自己的系统状态,包含内存状态.打开文件列表.追踪指令执行情况的程序指针以及一个保存局部变量的调用栈.通常情况下,一个进程依照一个单序列控制流顺序执行,这个控制流被称为该进程的主线程.在任何给定的时刻,一个程序只做一件事情. 一个程序可以通过Python库函数中的os或subprocess模块创建新进程(例如os.fork()或是subprocess.Popen()).然而,这些被称为子进程的进程却是独立运行的,它们有各自独立的系统状态以及

  • Python并发编程之未来模块Futures

    目录 区分并发和并行 并发编程之Futures 到底什么是Futures? 为什么多线程每次只有一个线程执行? 总结 不论是哪一种语言,并发编程都是一项非常重要的技巧.比如我们上一章用的爬虫,就被广泛用在工业的各个领域.我们每天在各个网站.App上获取的新闻信息,很大一部分都是通过并发编程版本的爬虫获得的. 正确并合理的使用并发编程,无疑会给我们的程序带来极大性能上的提升.今天我们就一起学习Python中的并发编程——Futures. 区分并发和并行 我们在学习并发编程时,常常会听到两个词:并发

  • Python基础教程之利用期物处理并发

    前言 抨击线程的往往是系统程序员,他们考虑的使用场景对一般的应用程序员来说,也许一生都不会遇到--应用程序员遇到的使用场景,99% 的情况下只需知道如何派生一堆独立的线程,然后用队列收集结果. 本文章记录了本人在学习Python基础之控制流程篇的重点知识及个人心得,打算入门Python的朋友们可以来一起学习并交流. 本文重点: 1.掌握异步编程的相关概念: 2.了解期物future的概念.意义和使用方法: 3.了解Python中的阻塞型I/O函数释放GIL的特点. 一.异步编程相关概念 阻塞:程

  • Python并发编程实例教程之线程的玩法

    目录 一.线程基础以及守护进程 二.线程锁(互斥锁) 三.线程锁(递归锁) 四.死锁 五.队列 六.相关面试题 七.判断数据是否安全 八.进程池 & 线程池 总结 一.线程基础以及守护进程 线程是CPU调度的最小单位 全局解释器锁 全局解释器锁GIL(global interpreter lock) 全局解释器锁的出现主要是为了完成垃圾回收机制的回收机制,对不同线程的引用计数的变化记录的更加精准. 全局解释器锁导致了同一个进程中的多个线程只能有一个线程真正被CPU执行. GIL锁每执行700条指

  • Python多进程并发与多线程并发编程实例总结

    本文实例总结了Python多进程并发与多线程并发.分享给大家供大家参考,具体如下: 这里对python支持的几种并发方式进行简单的总结. Python支持的并发分为多线程并发与多进程并发(异步IO本文不涉及).概念上来说,多进程并发即运行多个独立的程序,优势在于并发处理的任务都由操作系统管理,不足之处在于程序与各进程之间的通信和数据共享不方便:多线程并发则由程序员管理并发处理的任务,这种并发方式可以方便地在线程间共享数据(前提是不能互斥).Python对多线程和多进程的支持都比一般编程语言更高级

随机推荐