今日内容
同步与异步
用来表达任务的提交方式
同步
提交完任务之后原地等待人物的返回结果 期间不做任何事
异步
提交完任务之后不原地等待任务的返回结果 直接去做其他事 有结果自动通知
阻塞与非阻塞
用来表达任务的执行状态
阻塞
阻塞态
非阻塞
就绪态、运行态
综合使用
同步阻塞
同步非阻塞
异步阻塞
异步非阻塞(效率最高)
创建进程的多种方式
'''
1.鼠标双击软件图标
2.python代码创建进程
'''
方式一:
from multiprocessing import Process
import time
def task(name):
time.sleep(2)
print(1111,name)
time.sleep(3)
print(22222,name)
'''
在不同的操作系统中创建进程底层原理不一样
windows
以导入模块的形式创建进程
linux/mac
以拷贝代码的形式创建进程
'''
if __name__ == '__main__':
p1 = Process(target=task,args=('你好',))
p1.start()
print(333)
方式二:
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self,name):
super().__init__()
self.name = name
def run(self):
print(111)
time.sleep(2)
print(222)
if __name__ == '__main__':
obj = MyProcess('jason')
obj.start()
print(333)
进程间数据隔离
同一台计算机上的多个进程数据是严格意义上的物理隔离(默认情况下)
from multiprocessing import Process
import time
money = 100
def task():
global money
time.sleep(3)
money = 10
print(money)
if __name__ == '__main__':
p1 = Process(target=task)
p1.start()
time.sleep(2)
print(money)
进程的join方法
from multiprocessing import Process
import time
def task(name,n):
print('%s 1111 '% name)
time.sleep(2)
print('%s 2222' % name)
if __name__ == '__main__':
p1 = Process(target=task, args=('jason',1))
p2 = Process(target=task, args=('joyce',3))
#p.start() #异步
'''主进程代码等待子进程代码运行结束再执行'''
#p.join()
#print(333)
start_time = time.time()
p1.start()
p2.start()
p1.join()
p2.join()
print(time.time()-start_time)
IPC机制
IPC:进程间通信
消息队列:存储数据的地方 所有人都可以存 也都可以取
from multiprocessing import Queue
q = Queue(3) #括号内可以指定存储数据的个数
#往消息队列中存放数据
q.put(100000)
q.put(2)
q.put(231)
print(q.get())
q.put(123)
print(q.full())
#判断队列是否已满 bool值
print(q.get())
print(q.get())
print(q.get())
#从消息队列中取数据
print(q.empty())
#判断队列是否是空的
'''
指定存数据的个数 数据超了不会报错
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('主')
生产者消费者模型
'''回想爬虫'''
生产者:
负责生产数据的'人'
消费者:
负责处理数据的'人'
该模型除了有生产者和消费者之外还必须有消息队列(只要是能够提供数据保存服务和提供服务的理论上都可以)
进程对象的多种方法
1.如何查看进程号
from multiprocessing import Process,current_process
current_process()
current_process().pid
import os
os.getpid()
os.getppid()
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__':
p1 = Process(target=task, args=('大张红',))
p1.daemon = True
p1.start()
time.sleep(1)
print('恕瑞玛皇帝:小吴勇嗝屁了')
僵尸进程与孤儿进程
僵尸进程
进程执行完毕后并不会立刻销毁所有的数据 会有一些信息短暂保留下来
比如进制号、进制时间、进程消耗功率等给父进程查看
ps:所有的进程都会变成僵尸进程
孤儿进程
子进程正常运行 父进程意外死亡 操作系统针对孤儿进程会派遣福利院管理
多进程数据错乱问题
模拟抢票软件
from multiprocessing import Process
import time
import json
import random
# 查票
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)
buy(name)
if __name__ == '__main__':
for i in range(10):
p = Process(target=run, args=('用户%s'%i, ))
p.start()
"""
多进程操作数据很可能会造成数据错乱>>>:互斥锁
互斥锁
将并发变成串行 牺牲了效率但是保障了数据的安全
"""
标签:__,name,编程,网络,并发,time,print,import,进程
From: https://www.cnblogs.com/lzy199911/p/16904785.html