Python并发编程 06 进程、协程

文章目录

  • 一、多进程调用
  • 二、Process类
    • 1、主要参数
    • 2、实例方法
    • 3、属性
    • 4、代码示例
  • 三、进程通讯
    • 1、进程队列通讯
    • 2、管道通讯
    • 3、Manager对象
  • 四、进程同步
  • 五、进程池
  • 六、协程
    • 1、协程简述
    • 2、用greenlet库实现协程
    • 3、用gevent库实现协程

一、多进程调用

与多线程调用相似

from multiprocessing import Process
import timedef f(name):time.sleep(1)print("hello",name,time.strftime("%X"))if __name__ == '__main__':print("start",time.strftime("%X"))p_list=[]for i in range(3):p = Process(target=f, args=("LuMX",))p_list.append(p)p.start()for i in p_list:i.join()print("end",time.strftime("%X"))
'''
start 15:09:57
hello LuMX 15:09:59
hello LuMX 15:09:59
hello LuMX 15:09:59
end 15:09:59
'''
from multiprocessing import Process
import timeclass MyProcess(Process):def run(self):time.sleep(1)print("hello",self.name,time.strftime("%X"))if __name__ == '__main__':print("start",time.strftime("%X"))for i in range(3):p=MyProcess()p.daemon=Truep.start()print("end",time.strftime("%X"))'''
start 15:26:31
end 15:26:31
'''
from multiprocessing import Process
import os, timedef info(title):print("title:", title)print("parent process:", os.getppid())  # 父进程的IDprint("process id", os.getpid())if __name__ == '__main__':info("main process line")time.sleep(1)print("----------------")p = Process(target=info,args=("LuMX",))p.start()p.join()'''
title: main process line
parent process: 9660
process id 12900
----------------
title: LuMX
parent process: 12900
process id 14000
'''

二、Process类

1、主要参数

target:要执行的方法
name:进程名
args/kwargs:要传入方法的参数

2、实例方法

is_alive():返回进程是否在运行
join([timeout]):阻塞当前环境的进程,直到调用此方法的进程终止或到达指定的timeout。
start():进程准备就绪,等待CPU调度
run():start()调用run方法,如果实例化进程时未指定传入target,则start默认执行run方法
terminate():不管任务是否完成,立即停止工作进程。

3、属性

daemon:和线程的setDaemon功能一样
name:进程名字
pid:进程号

4、代码示例

import time
from multiprocessing import Processclass MyProcess(Process):def __init__(self,num,name):super(MyProcess,self).__init__(name=name)self.num=numdef run(self):time.sleep(1)print(f"name:{self.name} pid:{self.pid} alive:{self.is_alive()} num:{self.num}",time.strftime("%X"))time.sleep(10)if __name__ == '__main__':print("main process start",time.strftime("%X"))p_list=[]for i in range(4):p = MyProcess(i,f"L{i}")p_list.append(p)for p in p_list:p.start()for p in p_list:p.join(1)print("main process end",time.strftime("%X"))

三、进程通讯

1、进程队列通讯

import queue,time
import multiprocessing
def foo(q):time.sleep(1)print("son process",id(q))q.put(123)q.put("haha")if __name__ == '__main__':q=multiprocessing.Queue() # 进程队列p=multiprocessing.Process(target=foo,args=(q,))p.start()print("main process",id(q))print(q.get())print(q.get())'''
main process 2032743575504
son process 2174242762864
123
haha
'''

2、管道通讯

from multiprocessing import Process, Pipe
import timedef f(conn):time.sleep(3)conn.send([12, {"age": 18}, "hellow"])response=conn.recv()print("response",response)conn.close()print("ID2:",id(conn))if __name__ == '__main__':parent_conn, child_conn = Pipe() # 返回两个双向管道print("ID1",id(child_conn))p=Process(target=f,args=(child_conn,))p.start()print(parent_conn.recv())time.sleep(2)parent_conn.send("hellow,Son")p.join()

3、Manager对象

进程队列和管道均是进程间通讯,即进程A的数据信息发送给进程B。
Manager对象支持进程数据共享,即进程A修改数据后,进程B访问该数据,是修改后的结果。
Manager对象支持的数据类型有:list, dict, Namespace, Lock, RLock, Semaphore, Queue等。

from multiprocessing import Process,Managerdef f(d,l,n):d[n] = "1"d["2"] = 2l.append(n)if __name__ == '__main__':with Manager() as manager:d=manager.dict()    # 设置一个字典对象为共享数据l=manager.list()    # 设置一个列表对象为共享数据p_list=[]for i in range(5):p = Process(target=f,args=(d,l,i))p.start()p_list.append(p)for res in p_list:res.join()print(d)    # {1: '1', '2': 2, 0: '1', 2: '1', 3: '1', 4: '1'}print(l)    # [1, 0, 2, 3, 4]

四、进程同步

from multiprocessing import Process,Lock
import timedef f(l,i):l.acquire()time.sleep(1)print("hellow world %s" %i)l.release()if __name__ == '__main__':lock = Lock()for num in range(5):Process(target=f, args=(lock,num)).start()

在上述例子中,各个进程并发申请向屏幕打印内容。如果不进行进程同步,可能上一个进程还没打印完,下一个进程就开始打印,造成窜行。

五、进程池

有50个任务,每个任务执行时间1s。如果开50个进程同时干,对系统资源的开销太大。而只开1个进程干,又太浪费时间。而进程池就是一个折中的方法。
进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程。如果进程池序列中没有可供使用的进程,程序就会等待。
进程池中有两个方法:
aplly: 同步接口
apply_async: 异步接口

from multiprocessing import Process,Pool
import time,osdef Foo(i):time.sleep(1)print(i,time.strftime("%X"))print("son",os.getpid())return "hello %s" %idef Bar(arg):print("arg:",arg)   # args为Foo返回值print("Bar:",os.getpid())if __name__ == '__main__':pool = Pool(5)  # 进程池中开5个进程同时干活print("main pid",os.getpid())for i in range(50):pool.apply_async(func=Foo,args=(i,),callback=Bar)# func:表示要执行的函数。# args:表示向执行函数传递的参数# callback:表示回调函数,就是func函数执行成功后再去执行的函数,它在主进程里运行# 下面两句代码顺序是固定的pool.close()    # 进程池不再接受新的任务pool.join()     # 等待所有任务执行完成print("end")

六、协程

1、协程简述

协程又称微线程,是非抢占式的,底层实现是用yield语句切换函数。协程主要解决的也是IO操作密集型问题。协程实际上就是一个线程在执行,所以省去线程切换的开销,也不需要多线程的锁机制。
用多进程+协程的方法,既可以充分利用多核,又充分发挥协程的高效率。

import timedef consumer(name):print("-->ready to eat baozi...")while True:new_baozi = yieldprint("[%s] is eating baozi %s" % (name, new_baozi))def producer():con.__next__()con2.__next__()n = 0while n<=10:time.sleep(1)print("producer is making baozi %s and %s" % (n, n + 1))con.send(n)con2.send(n + 1)n += 2print("-----------")if __name__ == '__main__':con = consumer("c1")con2 = consumer("c2")producer()

2、用greenlet库实现协程

from greenlet import greenletdef test1():print(12)gr2.switch()print(34)def test2():print(56)gr1.switch()    # 切换到test1print(78)gr1.switch()# 返回两个greenlet对象,不需要再提前声明为生成器函数
gr1 = greenlet(test1)
gr2 = greenlet(test2)print(gr1)
gr2.switch()    # 切换到test2'''
<greenlet.greenlet object at 0x000002417FDECC00 (otid=0x0000000000000000) pending>
56
12
78
34
'''

3、用gevent库实现协程

gevent库比greenlet库进一步简化操作,可以不用手动切换协程,IO阻塞时,自动完成切换。

import gevent
import requests,timestart = time.time()def f(url):print("GET: %s" %url)resp = requests.get(url)    # 爬取网页数据data = resp.textprint("%d bytes received from %s" %(len(data), url))# joinall方法:等待一组Greenlet(协程)完成
gevent.joinall([# spawn方法作用是创建一个协程gevent.spawn(f, 'https://www.python.org/'),gevent.spawn(f, 'https://www.yahoo.com/'),gevent.spawn(f, 'https://www.baidu.com/'),gevent.spawn(f, 'https://www.sina.com.cn/'),
])print("cost time:", time.time()-start)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/18418.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最强端侧多模态模型MiniCPM-V 2.5,8B 参数,性能超越 GPT-4V 和 Gemini Pro

前言 近年来&#xff0c;人工智能领域掀起了一股大模型热潮&#xff0c;然而大模型的巨大参数量级和高昂的算力需求&#xff0c;限制了其在端侧设备上的应用。为了打破这一局限&#xff0c;面壁智能推出了 MiniCPM 模型家族&#xff0c;致力于打造高性能、低参数量的端侧模型。…

leetcode 802.找到最终的安全状态

思路&#xff1a;拓补排序 其实这道题只要把顺序倒过来就行了&#xff0c;我们首先看到没有出度的反而是终端点&#xff0c;我们不如让它反过来成为没有入度的点是终端店&#xff0c;这样的话我们用度的个数来找到终端点就很容易了。 那么这样的话&#xff0c;题目中说若点满…

微信小程序 蓝牙打印esc编码格式

esc.js var encode require("./encoding.js") var app getApp(); var jpPrinter {    createNew: function() {      var jpPrinter {};var data [];var bar ["UPC-A", "UPC-E", "EAN13", "EAN8", "C…

【深度学习】xformers与pytorch的版本对应关系

https://github.com/facebookresearch/xformers/tree/v0.0.23 找tag&#xff1a; tag下面写了对应关系&#xff1a; 安装指令就是&#xff1a; pip install xformers0.0.23 --no-deps -i https://download.pytorch.org/whl/cu118

react ant 表格实现 拖拽排序和多选

项目背景 : react ant 要实现 : 有多选功能(实现批量删除 , 也可以全选) 可以拖拽(可以复制 , 方便顶部的搜索功能) 要实现效果如下 1 这是最初的拖拽功能实现 , 不能复制表格里的内容 , 不符合要求 2 更改了ROW的内容 , 实现了可以复制表格内容 代码 //控制是否可以选中表格…

Unity中自动生成地图(代完善)

地图中有水果、房子、树木和道路。道路能通到水果旁。 代码&#xff1a; using UnityEngine; using System.Collections.Generic; using System.Text;public class TilemapGenerator : MonoBehaviour {public int mapWidth 30;public int mapHeight 20;private int[,] map;…

基于粒子群算法的网络最优节点部署优化matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于粒子群算法的网络最优节点部署优化,实现WSN网络的节点覆盖最大化。 2.测试软件版本以及运行结果展示 MATLAB2022A版本运行 3.核心程序 .................…

Golang | Leetcode Golang题解之第118题杨辉三角

题目&#xff1a; 题解&#xff1a; func generate(numRows int) [][]int {ans : make([][]int, numRows)for i : range ans {ans[i] make([]int, i1)ans[i][0] 1ans[i][i] 1for j : 1; j < i; j {ans[i][j] ans[i-1][j] ans[i-1][j-1]}}return ans }

安装WordPress

第 1 步&#xff1a;下载并解压 wget https://wordpress.org/latest.tar.gz 然后使用以下命令提取包&#xff1a; tar -xzvf latest.tar.gz 第 2 步&#xff1a;创建数据库 比如数据库名称为wordpress&#xff0c;编码格式为 utf8mb4_general_ci 第 3 步&#xff1a;设置wp-con…

Notes for video: EDC-Con 2022/01 - EDC Conceptual Overview and Architecture

Eclipse Dataspace Connector 中文概念 Eclipse Dataspace Connector (EDC) 是一个开源项目&#xff0c;旨在提供一种标准化的方法来连接和共享数据空间中的数据。它是 Eclipse Foundation 下的一个项目&#xff0c;目标是促进数据共享和数据交换的互操作性。以下是 EDC 的一些…

【STL库源码剖析】list 简单实现

从此音尘各悄然 春山如黛草如烟 目录 list 的结点设计 list 的迭代器 list 的部分框架 迭代器的实现 容量相关相关函数 实现 insert 在指定位置插入 val 实现 push_back 在尾部进行插入 实现 erase 在指定位置删除 实现 pop_back 在尾部进行删除 实现 list 的头插、头删 实现…

代码质量与可维护性提升

代码质量和可维护性的提升是一个持续的过程&#xff0c;需要在开发过程中采取一系列的措施。下面是一些可以提高代码质量和可维护性的方法&#xff1a; 使用清晰的命名&#xff1a;使用有意义且易于理解的变量名、函数名和类名。这样可以增加代码的可读性和可理解性。 遵循编码…

CSS:cursor作用

cursor作用 介绍常用值及用途1. default:2. pointer:3. text:4. move:5. not-allowed:6. wait:7. crosshair:8. col-resize:9. row-resize:10. grab:11. grabbing: 举例 介绍 Web开发中&#xff0c;cursor 是一个CSS属性&#xff0c;用于控制当鼠标指针悬停在一个元素上时显示…

Leetcode3161. 物块放置查询(Go语言的红黑树 + 线段树)

题目截图 题目分析 每次1操作将会分裂成两块区间长度&#xff0c;以最近右端点记录左侧区间的长度即可 因此涉及到单点更新和区间查询 然后左右侧最近端点则使用redBlackTree&#xff0c;也就是python中的sortedlist ac code type seg []int// 把 i 处的值改成 val func (t …

【小呆的力学笔记】连续介质力学的知识点回顾二:应变度量

文章目录 3. 格林应变与阿尔曼西应变 3. 格林应变与阿尔曼西应变 变形体在变形前的线元 O A → \overrightarrow{OA} OA &#xff0c;在变形后变成 o a → \overrightarrow{oa} oa &#xff0c;那么应变应该度量这种线元变形前后的差别。 ∣ o a → ∣ 2 − ∣ O A → ∣ 2 …

OrangePi AIpro开箱评测

开箱评测 有幸受邀参与了CSDN与OrangePi组织的评测活动&#xff0c;今天刚收到快递。拆开快递能看到保护盒、电源、双头typec线这三样&#xff08;充电器和线有保护膜的我先拆掉了&#xff09; 打开保护盒&#xff0c;能看到上下两块黑色海棉包裹的开发板&#xff08;保护得不…

cs61B-sp21 | lab6

cs61B-sp21 | lab6 TODO 1 在 CapersRepository.java 中 static final File CAPERS_FOLDER null; // TODO Hint: look at the join // function in Utils在 Utils.java 我们找到 join 函数&#xff0c;第一个 join 的作用是将 first 和 others 连接起来形成一个路径…

IDEA2024创建maven项目

1、new->project 2、创建后展示 3、生成resources文件夹 4、测试--编写一个hello文件

react-server-side-render最新学习与实践

写在前面 server side render(ssr)服务端渲染 &#xff0c;亦即同构应用。主要有利于 seo 和首屏渲染&#xff0c;这是一篇比较新的可运行的结构设计&#xff0c;基于比较新的 react v16、react-router v5 的同构设计。结合了 redux(Flux 数据流实现)。 项目地址:react-ssr-s…

[书生·浦语大模型实战营]——在茴香豆 Web 版中创建自己领域的知识问答助手

茴香豆是一个基于LLM的领域知识助手&#xff0c;可以用于解答群聊中的问题。接下来是创建过程。 1.打开茴香豆Web版&#xff0c;创建自己的领域库。 地址&#xff1a;茴香豆Web版 这里类似于注册账号&#xff0c;你输入知识库的名称以及密码&#xff0c;然后它就会创建一个知识…