同步与异步、阻塞与非阻塞、创建进程的多种方式、进程间数据隔离、进程的join方法、IPC机制等

2023-02-14,,,,

目录
同步与异步
阻塞与非阻塞
综合使用
创建进程的多种方式
进程间数据隔离
进程的join方法
IPC机制
生产者消费者模型
进程对象的多种方法
守护进程
僵尸进程与孤儿进程
多进程数据错乱问题

同步与异步

用来表达任务的提交方式

同步
提交完任务之后原地等待任务的返回结果 期间不做任何事
异步
提交完任务之后不愿地等待任务的返回结果 直接去做其他事 有结果自动通知

阻塞与非阻塞

用来表达任务的执行状态

阻塞
阻塞态
非阻塞
就绪态、运行态

综合使用

同步阻塞
同步非阻塞
异步阻塞
异步非阻塞(******)
效率最高

创建进程的多种方式

"""
1.鼠标双击软件图标
2.python代码创建进程
"""
"""
在不同的操作系统中创建进程底层原理不一样
windows
以导入模块的形式创建进程
linux/mac
以拷贝代码的形式创建进程
"""
from multiprocessing import Process
import time def task():
print('task is running')
time.sleep(3)
print('task is over') if __name__ == '__main__':
p1 = Process(target=task)
p1.start()
# task()
print('主')
from multiprocessing import Process
import time class MyProcess(Process):
def run(self):
print('run is running')
time.sleep(3)
print('run is over')
if __name__ == '__main__':
obj = MyProcess()
obj.start()
print('主')
# 创建进程的两种方式的传参
from multiprocessing import Process
import time def task(name):
print('task is running',name)
time.sleep(3)
print('task is over',name) if __name__ == '__main__':
p1 = Process(target=task, args=('jason',)) # 位置参数
p1 = Process(target=task, kwargs={'name':'jason123'}) # 关键字参数
p1.start() # 异步 告诉操作系统创建一个新的进程 并在该进程中执行task函数
# task() # 同步
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('主')

进程间数据隔离

同一台计算机上的多个进程数据是严格意义上的物理隔离(默认情况下)

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

进程的join方法

from 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))
# p.start() # 异步
'''主进程代码等待子进程代码运行结束再执行'''
# p.join()
# print('主')
start_time = time.time()
p1.start()
p1.join()
p2.start()
p2.join()
p3.start()
p3.join()
print(time.time() - start_time) # 6秒多 p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
print(time.time() - start_time) # 3秒多

IPC机制

IPC:进程间通信
消息队列:存储数据的地方 所有人都可以存 也都可以取 from multiprocessing import Queue q = Queue(3) # 括号内可以指定存储数据的个数
# 往消息队列中存放数据
q.put(111)
# print(q.full()) # 判断队列是否已满
q.put(222)
q.put(333)
# print(q.full()) # 判断队列是否已满
# 从消息队列中取出数据
print(q.get())
print(q.get())
# print(q.empty()) # 判断队列是否为空
print(q.get())
# print(q.empty()) # 判断队列是否为空
# 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('主')

生产者消费者模型

"""回想爬虫"""
生产者
负责产生数据的'人'
消费者
负责处理数据的'人' 该模型除了有生产者和消费者之外还必须有消息队列(只要是能够提供数据保存服务和提取服务的理论上都可以)

进程对象的多种方法

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()

守护进程

守护进程会随着守护的进程结束而立刻结束
eg: jason是kevin的守护进程 一旦kevin嗝屁了 jason立刻嗝屁 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=('kevin',))
p1.daemon = True
p1.start()
time.sleep(1)
print('恕瑞玛皇帝:jason去世了')

僵尸进程与孤儿进程

僵尸进程
进程执行完毕后并不会立刻销毁所有的数据 会有一些信息短暂保留下来
比如进程号、进程执行时间、进程消耗功率等给父进程查看
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() """
多进程操作数据很可能会造成数据错乱>>>:互斥锁
互斥锁
将并发变成串行 牺牲了效率但是保障了数据的安全
"""

同步与异步、阻塞与非阻塞、创建进程的多种方式、进程间数据隔离、进程的join方法、IPC机制等的相关教程结束。

《同步与异步、阻塞与非阻塞、创建进程的多种方式、进程间数据隔离、进程的join方法、IPC机制等.doc》

下载本文的Word格式文档,以方便收藏与打印。