进程之multiprocessing模块代码篇
这里再把之前的内容总结和补充一下:
并发和并行:
你在干坏事,来了一个电话,干完坏事再去接电话,说明你既不是并发也不是并行。
你在干坏事,来了一个电话,你接完电话接着干坏事,说明你支持并发
你在干坏事,来了一个电话,你边接电话边干坏事,说明你支持并行
同步和异步:
同步:要想执行下一步 必须等待上一步执行完
异步:想要调用一个函数 只需要通知就行了 不需要等待结果就可以继续执行其他代码
下面简单的来一段代码如何让服务端实现并发的效果
#服务端
import socket
from multiprocessing import Process
def talk(conn):
conn.send(b'connected') #只要客户端一链接就发过去去一条信息
ret = conn.recv(1024)
print(ret)
if __name__ == '__main__':
sk = socket.socket()
sk.bind(('127.0.0.1', 8080))
sk.listen()
while True:
conn,addr = sk.accept()
p = Process(target=talk,args=(conn,)) #在参数传过来实例化一个进程
p.start() #开启进程
conn.close()
sk.close() #客户端
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',8080))
ret = sk.recv(1024)
print(ret)
msg = input('>>>')
sk.send(msg.encode('utf-8'))
sk.close()
上面的代码只要一直执行客户端就能够实现一个服务端N个客户端的并发效果
start 开启一个进程
join 用join可以让主进程等待子进程结束 守护进程
二话不说上代码
# 守护进程
# 守护进程会随着主进程的代码执行结束而结束
# 正常的子进程没有执行完的时候主进程要一直等着
import time
from multiprocessing import Process
def func():
print('--'*10)
time.sleep(15)
print('--'*10)
def cal_time(): #这个子进程变为了守护进程
while True:
time.sleep(1)
print('过去了1秒') if __name__ == '__main__':
p = Process(target=cal_time)
p.daemon = True # 一定在开启进程之前设置,此处开启了守护进程
p.start()
p2 = Process(target=func) # 15s
p2.start()
for i in range(100): # 10s
time.sleep(0.1)
print('*'*i)
#p2.join() #一旦开启join,守护进程也会等待子进程,因为主进程在等待子进程 # 守护进程的进程的作用:
# 会随着主进程的代码执行结束而结束,不会等待其他子进程
# 守护进程 要在start之前设置
# 守护进程中 不能再开启子进程
import time
from multiprocessing import Process
def func():
print('wahaha')
time.sleep(5)
print('qqxing')
if __name__ == '__main__':
p = Process(target=func)
p.start()
print(p.is_alive())
time.sleep(0.1)
p.terminate() # 关闭进程 异步
print(p.is_alive())
time.sleep(1)
print(p.is_alive()) p.is_alive() # 是否活着 True代表进程还在 False代表进程不在了
p.terminate() # 结束一个进程,但是这个进程不会立刻被杀死,由操作系统决定什么时候死
进程的其他方法
属性
pid 查看这个进程 进程id
name 查看这个进程的名字 def func():
print('wahaha')
time.sleep(5)
print('qqxing')
if __name__ == '__main__':
p = Process(target=func)
p.start()
print(p.name,p.pid)
p.name = '哇哈哈哈' #修改了name的名字
print(p.name) class MyProcess(Process):
def run(self):
print('wahaha',self.name,self.pid)
time.sleep(5)
print('qqxing',self.name,self.pid)
if __name__ == '__main__':
p = MyProcess()
p.start()
print(p.pid) 进程中的其他方法
守护进程 p.daemon = True
两个方法 p.is_alive() p.terminate()
两个属性 p.pid p.name
锁
在我们费心费力的实现异步并发,提高cpu的利用率的时候,经常会出现多个进程为了抢占输出资源。
锁的存在就是为了梳理这些进程之间的关系
from multiprocessing import Lock
lock = Lock()
lock.acquire() # 需要锁 拿钥匙
lock.acquire() # 需要锁 连续两次拿钥匙阻塞 lock.release() # 释放锁 还钥匙 锁 就是在并发编程中 保证数据安全
下面模拟一下春运抢票
import json
import time
import random
from multiprocessing import Lock
from multiprocessing import Process
def search(i):
with open('ticket') as f: #打开一个ticket文件,里面存放了{"count": 0}
print(i,json.load(f)['count']) #load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
def get(i):
with open('ticket') as f:
ticket_num = json.load(f)['count']
time.sleep(random.random()) #时间在这里停了大于0且小于1之间的小数
if ticket_num>0: #如果文件中的count对应的值大于0
with open('ticket','w') as f:
json.dump({'count':ticket_num-1},f) #dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件
print('%s买到票了'%i) #打印结果并且数量减一
else:
print('%s没票了'%i)
def task(i,lock):
search(i) #查票
lock.acquire() #拿到一把锁
get(i) #抢票
lock.release() #释放锁
if __name__ == '__main__':
lock = Lock() #实例化一把锁
for i in range(20): #20个人同时抢票
p = Process(target=task,args=(i,lock)) #实例化一个进程对象
p.start() #执行这个进程
信号量
import time
import random
from multiprocessing import Semaphore
from multiprocessing import Process
def sing(i,sem):
sem.acquire()
print('%s : 进入 ktv'%i)
time.sleep(random.randint(1,10))
print('%s : 出 ktv'%i)
sem.release()
# 迷你唱吧 20个人,同一时间只能有4个人进去唱歌
if __name__ == '__main__':
sem = Semaphore(4) #这里限制了一次最多几个进程执行
for i in range(20):
Process(target=sing,args=(i,sem)).start()
事件
所有的阻塞 都是同步
recv accept input sleep
阻塞多个进程 异步阻塞
事件 —— 异步阻塞
事件 标志 同时 是所有的进程 都陷入阻塞
from multiprocessing import Event #事件
e = Event() # 实例化一个事件 标志/交通信号灯
e.set() # 将标志变成非阻塞/交通灯变绿
e.wait() # 刚实例化出来的一个事件对象,默认的信号是阻塞信号/默认是红灯,执行到wait,要先看灯,绿灯行红灯停,如果在停的过程中灯绿了,就变成非阻塞了
e.is_set()是否非阻塞 True就是绿灯 False就是红灯
下面就举例马路上的红绿灯来看一下事件
import time
import random
from multiprocessing import Process
from multiprocessing import Event
def traffic_light(e):
while True:
if e.is_set(): #判断是红灯还是绿灯
time.sleep(3)
print('红灯亮')
e.clear() # 绿变红
else:
time.sleep(3)
print('绿灯亮')
e.set() # 红变绿
def car(i,e):
e.wait()
print('%s车通过'%i)
if __name__ == '__main__':
e = Event() # 立一个红灯
tra = Process(target=traffic_light,args=(e,))
tra.start() # 启动一个进程来控制红绿灯
for i in range(100):
if i%6 == 0 :
time.sleep(random.randint(1,3))
car_pro = Process(target=car, args=(i,e))
car_pro.start()
通过上述代码可以看出,Event模块的作用就是通过判断是否阻塞然后来改变阻塞状态来实现自己想要的效果 队列 it行业当中总会有一些莫名其妙的需求,这是一种钻研精神。比如,现在某个人有一种想法,能不能实现两个进程之间的通话呢?
from multiprocessing import Queue
q = Queue(2) #这里不传参数就会默认数据长度无限制,现在限制最多只能放两个值,如果放三个值是放不进去的
q.put(1)
q.put(2)
q.put(3) #put()是放数据,现在放了三个
print(q.get())
print(q.get())
print(q.get()) # get()往外拿值
print(q.get()) # 前面一共放了三个值,如果队列里已经没有值了 就会阻塞等待有一个值 1.进程之间通信 可以使用multiprocessing 的 Queue模块
2.队列有两种创建方式 第一种不传参数 这个队列就没有长度限制 ;如果传参数,则创建一个有最大长度限制的队列
3.提供两个重要方法;put get
from multiprocessing import Process
from multiprocessing import Queue
import random
def q_put(q):
q.put('hello') #往队列里放值
def q_get(q):
print(q.get()) #从队列里拿值
if __name__ =='__main__':
q = Queue()
p = Process(target=q_put,args=(q,))
p.start()
p1 = Process(target=q_get, args=(q,))
p1.start()
上面代码通过队列实现了,主进程与子进程的通信,子进程与子进程之间的通信
生产者消费者模型
我要生产一个数据 然后 给一个函数 让这个函数依赖这个数据进行运算 拿到结果 —— 同步过程
下面来一个做包子和吃包子的例子
import time
def producer(q): # 生产者
for i in range(100):
q.put('包子%s'%i) #生产者生产包子 def consumer(q): # 消费者
for i in range(100):
time.sleep(1)
print(q.get()) #消费者买包子 if __name__ == '__main__':
q = Queue(10) # 生产者做好的包子放在这里,一次放十个
p = Process(target=producer,args=(q,))
p.start()
c1 = Process(target=consumer, args=(q,))
c2 = Process(target=consumer, args=(q,)) #一个人买的太慢,再实例化一个消费者
c1.start()
c2.start() 首先 对于内存空间来说 每次只有很少的数据会在内存中
对于生产与消费之间的不平衡来说
增加消费者或者增加生产者来调节效率
进程之multiprocessing模块代码篇的更多相关文章
- 多进程之multiprocessing模块和进程池的实现
转载:https://www.cnblogs.com/xiaobeibei26/p/6484849.html Python多进程之multiprocessing模块和进程池的实现 1.利用multip ...
- Python多进程之multiprocessing模块和进程池的实现
1.利用multiprocessing可以在主进程中创建子进程,提升效率,下面是multiprocessing创建进程的简单例子,和多线程的使用非常相似 ''' 代码是由主进程里面的主线程从上到下执行 ...
- 多进程之multiprocessing模块、守护进程、互斥锁
目录 1. multiprocessing 模块介绍 2. Process类的介绍 3. Process类的使用 4. 守护进程 5. 进程同步(锁) 1. multiprocessing 模块介绍 ...
- 进程之multiprocessing
进程的状态:
- python多进程之multiprocessing
什么是多进程? 简单的理解:单板上运行的一个程序就是一个进程.进程是操作系统分配资源的最小单位,不同的进程之间资源不共享,进程间通信需要使用特定的方式.python提供了自带的multiprocess ...
- 创建多进程之multiprocess包中的process模块
创建多进程之multiprocess包中的process模块 1.process模块是一个创建进程的模块 Process([group [, target [, name [, args [, kwa ...
- multiprocessing模块
multiprocessing模块 由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程. multiproce ...
- python MultiProcessing模块进程间通信的解惑与回顾
这段时间沉迷MultiProcessing模块不能自拔,没办法,python的基础不太熟,因此就是在不断地遇到问题解决问题.之前学习asyncio模块学的一知半解,后来想起MultiProcessin ...
- 30、进程的基础理论,并发(multiprocessing模块)
我们之前基于tcp所做的通信都只能一个一个链接只有关闭当前链接时才能去链接下一个通信,这显然与现实情况不合.今天我们将来学一个新的概念进程,来做一个python多进程的并发编程.还会贴一个用json序 ...
随机推荐
- Marked
哈夫曼树 2-sat问题 线性代数基础 矩阵和行列式基础 可并堆1 可并堆2 概率与期望概念 Kruskcl重构树1 Kruskcl重构树2 匈牙利算法 带权并查集 C++参考手册 尺取法 AC自动机 ...
- flink杂记
flink的特点:能同时满足高性能.高吞吐.低延时,相比较于storm和spark streaming,storm的吞吐量不如flink,而spark streaming的延时比较高,因为spark ...
- C++入门经典-例8.5-多重继承
1:C++允许子类从多个父类继承公有的和受保护的成员,这称为多重继承. 2:多重继承的定义.多重继承有多个基类名称标识符,其声明形式如下: class 派生类名标识符:[继承方式] 基类名标识符1,. ...
- Leetcode题目22.括号生成(动态规划-中等)
题目描述: 给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合. 例如,给出 n = 3,生成结果为: [ "((()))", "( ...
- 静态化-VeloCity
1.在spring.xml中配置 <!-- 指定vm模版路径 start --> <bean id="velocityEngine" class="or ...
- koa 基础(四)get 传值 以及获取 get 传值
1.get 传值 以及获取 get 传值 app.js /** * get 传值 以及获取 get 传值 */ // 引入模块 const Koa = require('koa'); const ro ...
- leetcode-hard-array-287. Find the Duplicate Number
mycode 77.79% class Solution(object): def findDuplicate(self, nums): """ :type nums ...
- ORA-00600: internal error code, arguments: [kdBlkCheckError]
ORA-00600: internal error code, arguments: [kdBlkCheckError] Table of Contents 1. 现象 2. 分析 3. 故障处理 1 ...
- 品牌logo在EDM数据营销中的运用
作为让客户识别并记住的“门面”, 品牌LOGO的设计与宣导一直都是品牌化输出的重中之重 . 而在邮件营销中,为了让用户在浏览邮件内容前先有品牌概念,营销人员在放置LOGO时常常仅把显眼突出纳入考虑因素 ...
- javascript之DOM四位的验证码简单实现
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...