Python 网络与并发编程(三)

server/2024/9/23 7:22:52/

文章目录

  • 进程Process
    • 优势:
    • 劣势
    • 进程的创建方式(方法模式)
    • 进程的创建方式(继承Process类)
    • Queue实现进程间通信
    • Pipe实现进程间通信
    • `Manager`管理器
    • 进程池(Pool)

进程Process

拥有自己独立的堆和栈,既不共享堆,也不共享栈,进程由操作系统调度;进程切换需要的资源很最大,效率低。

对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程,打开一个Word就启动了一个Word进程。

优势:

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

劣势

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

进程的创建方式(方法模式)

Python的标准库提供了个模块: multiprocessing
创建进程后,使用start()启动进程

python">#coding=utf-8
# 方法包装-多进程实现
from multiprocessing import Process
import os
from time import sleep
def func1(name):print("当前进程ID:",os.getpid())print("父进程ID:",os.getppid())print(f"Process:{name} start")sleep(3)print(f"Process:{name} end")
if __name__ =="__main__":print("当前进程ID:",os.getpid())# 创建进程p1 = Process(target=func1, args=('p1',))p2 = Process(target=func1, args=('p2',))p1.start()p2.start()

当前进程ID: 15256
当前进程ID: 4888
当前进程ID: 11388
父进程ID: 15256父进程ID: 15256
Process:p2 start
Process:p1 start
Process:p1 end
Process:p2 end

进程的创建方式(继承Process类)

和使用Thread 类创建子线程的方式非常类似,使用 Process 类创建实例化对象,其本质是调用该类的构造方法创建新进程。Process类的构造方法格式如下:

python">def __init__(self,group=None,target=None,name=None,args=(),kwargs={})

其中,group :该参数未进行实现,不需要传参;target :为新建进程指定执行任务,也就是指定一个函数;name :为新建进程设置名称;args :为 target 参数指定的参数传递非关键字参数;kwargs :为 target 参数指定的参数传递关键字参数。

python">from multiprocessing import Process
from time import sleep
class MyProcess(Process):def __init__(self, name):Process.__init__(self)self.name = namedef run(self):print(f"Process:{self.name} start")sleep(3)print(f"Process:{self.name} end")
if __name__ == "__main__":#创建进程p1 = MyProcess("p1")p2 = MyProcess("p2")p1.start()p2.start()

Process:p1 start
Process:p2 start
Process:p2 end
Process:p1 end

Queue实现进程间通信

前面讲解了使用 Queue 模块中的 Queue 类实现线程间通信,但要实现进程间通信,需要使用 multiprocessing 模块中的 Queue 类。
简单的理解 Queue 实现进程间通信的方式,就是使用了操作系统给开辟的一个队列空间,各个进程可以把数据放到该队列中,当然也可以从队列中把自己需要的信息取走。

python">
from multiprocessing import Process,Queue
class MyProcess(Process):def __init__(self,name,mq):Process.__init__(self)self.name = nameself.mq = mqdef run(self):print("Process:{}start".format(self.name))print('--------------',self.mq.get(),'-------------')self.mq.put(self.name)print("Process:{}end".format(self.name))
if __name__ == '__main__':# 创建进程列表t_list = []mq = Queue()mq.put('1')mq.put('2')mq.put('3')# 循环创建进程for i in range(3):t = MyProcess('p{}'.format(i),mq)t.start()t_list.append(t)# 等待进程结束for t in t_list:t.join()print(mq.get())print(mq.get())print(mq.get())

Process:p1start
Process:p2start
Process:p0start--------------
1 -------------
-------------- 2 -------------
-------------- 3 -------------
Process:p1end
Process:p0endProcess:p2end
p1
p0
p2

Pipe实现进程间通信

Pipe 直译过来的意思是“管”或“管道”,和实际生活中的管(管道)是非常类似的

Pipe方法返回(conn1, conn2)代表一个管道的两个端。

python">#coding=utf-8
import multiprocessing
from time import sleep
def func1(conn1):sub_info = "Hello!"print(f"进程1--{multiprocessing.current_process().pid}发送数据:{sub_info}")sleep(1)conn1.send(sub_info)print(f"来自进程2:{conn1.recv()}")sleep(1)
def func2(conn2):sub_info = "你好!"print(f"进程2--{multiprocessing.current_process().pid}发送数据:{sub_info}")sleep(1)conn2.send(sub_info)print(f"来自进程1:{conn2.recv()}")sleep(1)
if __name__ == '__main__':
# 创建管道conn1, conn2 = multiprocessing.Pipe()# 创建子进程process1 =	multiprocessing.Process(target=func1, args=	(conn1,))process2 =	multiprocessing.Process(target=func2, args=	(conn2,))# 启动子进程process1.start()process2.start()

进程2–15904发送数据:你好!进程1–6436发送数据:Hello!
来自进程2:你好!来自进程1:Hello!

Manager管理器

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

python">
#coding=utf-8
from multiprocessing import Process,current_process
from multiprocessing import Manager
def func(name,m_list,m_dict):m_dict['name'] = 'zhangsan'm_list.append('你好')
if __name__ == "__main__":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() #等p1进程结束,主进程继续执行print(m_list)print(m_dict)

[‘Hello!!’, ‘你好’]
{‘name’: ‘zhangsan’}

进程池(Pool)

类/方法功能参数
Pool(processes)创建进程池对象processes表示进程池中有多少进程
pool.apply_async(func,args,kwds)异步执行;将事件放入到进程池队列func 事件函数 args 以元组形式给func传参kwds 以字典形式给func传参 返回值:返回一个代表进程池事件的对象,通过返回值的get方法可以得到事件函数的返回值
pool.apply(func,args,kwds)同步执行;将事件放入到进程池队列func 事件函数 args 以元组形式给func传参kwds 以字典形式给func传参
pool.close()关闭进程池
pool.join()回收进程池
pool.map(func,iter)类似于python的map函数,将要做的事件放入进程池func 要执行的函数 iter 迭代对象
python">#coding=utf-8
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=('z1',),callback=func2)pool.apply_async(func = func1,args=('z2',),callback=func2)pool.apply_async(func = func1,args=('z3',),callback=func2)pool.apply_async(func = func1,args=('z4',))pool.apply_async(func = func1,args=('z5',))pool.apply_async(func = func1,args=('z6',))pool.apply_async(func = func1,args=('z7',))pool.apply_async(func = func1,args=('z8',))pool.close()pool.join()

当前进程的ID:18736,z1
当前进程的ID:17316,z2
当前进程的ID:12900,z3
当前进程的ID:10120,z4
当前进程的ID:1680,z5
当前进程的ID:10120,z6
当前进程的ID:17316,z7
当前进程的ID:1680,z8
z2
z1
z3


http://www.ppmy.cn/server/14087.html

相关文章

江开2024年春《大学英语(B)(2) 060052》过程性考核作业4参考答案

答案:更多答案,请关注【电大搜题】微信公众号 答案:更多答案,请关注【电大搜题】微信公众号 答案:更多答案,请关注【电大搜题】微信公众号 单选题 1阅读Passage One,回答C-1C-4个问题。请…

基于Python的图书借阅管理系统,附源码

博主介绍:✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇&#x1f3…

【Docker】有关docker操作命令

最近在使用docker以及docker-compose等进行项目环境搭建,以及项目的部署,有些命令记录一下: 删除所有镜像 docker rmi $(docker images -q) -f停止所有容器 docker stop $(docker ps -aq)进入容器内部 docker exec -it CONTAINER_ID /bin/bas…

python机器学习库中Scikit-learn和TensorFlow如何选择?

在Python机器学习库中,Scikit-learn和TensorFlow是两个非常流行的选择,但它们各自有不同的特点和适用场景。以下是根据搜索结果的一些考虑因素,帮助你做出选择: 1. 项目需求: 如果你的项目主要涉及传统的机器学习算…

黄金行情下跌有投资机会吗?

尽管黄金价格的波动常常引起投资者的高度关注,但行情的下跌未必只是警讯,亦可能蕴藏着某些难得的投资机会。总之,答案是肯定的——在黄金行情下跌时,依旧有适宜的投资机会,只是这需要投资者具备相应的应对知识和策略。…

Linux gcc day7

动态链接和静态链接 形成的可执行的程序小:节省资源--内存,磁盘 无法c静态库链接的方法 原因是我们没有安装静态c库(.a) 所以要安装 sudo yum install -y glibc-static gcc static静态编译选项提示错误:/usr/lib/ld:ca…

东岸科技将赴港IPO,冲刺催收第一股

来源 | 镭射财经(leishecaijing) 「镭射财经」独家获悉,东岸科技即将开启IPO,向港交所递交上市申请。计划上市的为公司科技板块,拟募集资金主要用于不良资产管理数字化创新。 今年3月,东岸科技董事长朱铁…

七星创客新零售系统:颠覆性商业模式的崛起

大家好,我是微三云周丽,今天给大家分析当下市场比较火爆的商业模式! 小编今天跟大伙们分享什么是七星创客新零售系统? 随着经济的快速发展和科技的不断进步,商业模式的革新成为了企业发展的关键。在这个新旧动能转换、…