目录
同步与异步
用来表达任务的提交方式
同步
提交完任务之后原地等待任务的返回结果 期间不做任何事
异步
提交完任务之后不愿地等待任务的返回结果 直接去做其它事 有结果自动通知
阻塞与非阻塞
用来表达任务的执行状态
阻塞
阻塞态
非阻塞
就绪态、运行态
综合使用
同步阻塞
同步非阻塞
异步阻塞
异步非阻塞(*****)
效率最高
创建进程的多种方式
什么情况下会用到多进程:想让某个函数反复的调用
方式一:
"""
1.鼠标双击软件图标
2.python代码创建进程
"""
from multiprocessing import Process
import time
def task(name):
print('task is running',name)
time.sleep(3)
print('task is over',name)
"""
在不同的操作系统中创建进程底层原理不一样
windows
以导入模块的形式创建进程
linux/mac
以拷贝代码的形式创建进程
"""
if __name__ == '__main__':
p1 = Process(target=task,args=('jason',)) # 位置参数,推荐使用这种方式
p1.start() # 异步方式调用子进程
print('主')
方式二:
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self, name, age):
super().__init__()
#派生方法顺序很重要,如果在修改值前面,那么修改值会替换父类相关属性,如果在修改值后面,会保留原来父类的属性
self.name = name
self.age = age
def run(self):
print('run is running', self.name,self.age)
time.sleep(3)
print('run is over',self.name , self.age)
if __name__ == '__main__':
obj = MyProcess('jason',123)
obj.start()
print('主')
'''
执行结果:
主
run is running jason 123
run is over jason 123
'''
进程间数据隔离
# 同一台计算机上的多个进程数据是严格意义上的物理隔离(默认情况下)
from multiprocessing import Process
import time
money = 1000
def task():
global money
money = 666
print('子进程的task函数查看money',money)
if __name__ == '__main__':
p1 = Process(target=task)
p1.start() # 创建子进程
time.sleep(3) # 主进程代码等待3秒
print(money) # 主进程代码打印money
"""
执行结果:
子进程的task函数查看money 666
1000
"""
进程的join方法
rom multiprocessing import Process
import time
def task(name, n):
print('%s is running' % name)
time.sleep(n)
print('%s is over' % name)
if __name__ == '__main__':
p1 = Process(target=task,args=('jason1',1))
p2 = Process(target=task,args=('jason2',2))
p3 = Process(target=task,args=('jason3',3))
start_time = time.time()
'''主进程代码等待子进程代码运行结束再执行'''
p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
"""
异步执行
执行结果:
jason1 is running
jason2 is running
jason3 is running
jason1 is over
jason2 is over
jason3 is over
主
3.0993828773498535
"""
# p1.start()
# p1.join()
# p2.start()
# p2.join()
# p3.start()
# p3.join()
'''运行结果:
同步执行
jason1 is running
jason1 is over
jason2 is running
jason2 is over
jason3 is running
jason3 is over
主
6.258119583129883
'''
print('主')
print(time.time()-start_time)
IPC机制
C:进程间通信
消息队列:存储数据的地方 所有人都可以存 也都可以取
from multiprocessing import Queue
q = Queue(3) # 括号内可以指定存储数据的个数
# 往消息队列中存放数据
q.put(111)
print(q.full()) # 判断队列是否已满 False
q.put(222)
q.put(333)
print(q.full()) # 判断队列是否已满 True
# 从消息队列中取出数据
print(q.get()) # 111
print(q.get()) # 222
print(q.empty()) # 判断队列是否为空 False
print(q.get()) # 333
print(q.empty()) # 判断队列是否为空 True
# print(q.get()) # 没有也不会报错
print(q.get_nowait()) # 如果队列为空会报错
"""
full() empty() 在多进程中都不能使用!!!
"""
from multiprocessing import Process, Queue
def product(q):
q.put('子进程p添加的数据')
def consumer(q):
print('子进程获取队列中的数据',q.get())
if __name__ == '__main__':
q = Queue()
# 主进程往队列中添加数据
# q.put('我是主进程添加的数据')
p1 = Process(target=consumer,args=(q,))
p2 = Process(target=product,args=(q,))
p1.start()
p2.start()
print('主')
"""
运行结果:
主
子进程获取队列中的数据 子进程p添加的数据
"""
生产者消费者模型
"""回想爬虫"""
生产者
负责产生数据的'人'
消费者
负责处理数据的'人'
该模型除了有生产者和消费者之外还必须有消息队列(只要是能够提供数据保存服务和提取服务的理论上都可以)
进程对象的多种方法
1.如何查看进程号
from multiprocessing import Process, current_process
print('current_process',current_process())
print('current_process-pid',current_process().pid)
'''
运行结果:
current_process <_MainProcess name='MainProcess' parent=None started>
current_process-pid 1736
'''
import os
print('os.getpid',os.getpid()) # os.getpid 1736
print('os.getppid',os.getppid()) # os.getppid 12812
# 2.终止进程
p1.terminate()
ps:计算机操作系统都有对应的命令可以直接杀死进程
3.判断进程是否存活
p1.is_alive()
4.start()
5.join()
守护进程
守护进程会随着守护的进程(主进程)的结束而结束
from multiprocessing import Process
import time
def task(name):
print('德邦总管:%s' % name)
time.sleep(3)
print('德邦总管: %s' % name)
if __name__ =='__main__':
start_time = time.time()
p1 = Process(target=task,args=('大红张',))
p1.daemon = True
p1.start()
time.sleep(1)
print('恕瑞玛皇帝:小吴勇嗝屁了')
print(time.time()-start_time)
'''
运行结果:
主程序运行了一秒后就强制把子进程给关闭了
德邦总管:大红张
恕瑞玛皇帝:小吴勇嗝屁了
1.0165724754333496
'''
僵尸进程与孤儿进程
僵尸进程
进程执行完毕后并不会立刻销毁所有的数据 会有一些信息短暂保留下来
比如进程号、进程执行时间、进程消耗功率等给父进程查看
ps:所有的进程都会变成僵尸进程
孤儿进程
子进程正常运行 父进程以外死亡 操作系统针对孤儿进程会派遣福利院管理
多进程数据错乱问题
from multiprocessing import Process,Lock
import time
import json
import random
lock = Lock()
# 查票
def search(name):
with open(r'data.json','r',encoding='utf8') as f:
data = json.load(f)
print('%s在查票 当前余票为:%s' %(name,data.get('ticket_num')))
# 买票
def buy(name):
# 再次确认票
with open(r'data.json','r',encoding='utf8') as f:
data = json.load(f)
# 模拟网络延迟
time.sleep(random.randint(1,3))
# 判断是否有票 有就买
if data.get('ticket_num') > 0:
data['ticket_num'] -= 1
with open(r'data.json','w',encoding='utf8') as f:
json.dump(data,f)
print('%s买票成功' %name)
else:
print('%s很倒霉 没有抢到票' %name)
def run(name):
search(name)
lock.acquire()
buy(name)
lock.release()
if __name__ == '__main__':
for i in range(10):
p = Process(target=run,args=('用户%s' %i,))
p.start()
# 如果没有加锁,数据会很混乱,导致所有人都能成功抢到票
标签:__,name,print,time,进程,import
From: https://www.cnblogs.com/winter-yu1989/p/16904182.html