import os
from multiprocessing import Process
class Myprocess(Process):
def run(self):
print(os.getpid(),os.getppid())
if __name__==‘__main__‘:
p = Myprocess()
p.start
属性:pid(进程序号),name(进程名)
方法:terminate(强制结束子进程。异步非阻塞),is_alive(查看子进程是否存活)
import time
from multiprocessing import Process
def func1():
while True:
print(‘in func1‘)
time.sleep(1)
if __name__==‘__main__‘:
p1 = Process(target=func1)
p1.daemon() = True # 将p1设置为一个守护进程
p1.start()
time.sleep(3)
"""
in func1
in func1
in func1
"""
# 正常情况下,主进程会等待所有的子进程结束(为了回收子进程的资源)
# 而守护进程会等待主进程的代码执行完后结束
# 注意!守护进程不会等待主进程中的其他子进程
当一段程序不想要多个进程同时执行的时候,可以设置一把锁,使得同一时间只有一个进程可以执行。比如12306买票的时候,如果只有1张车票了,但是同时有多个用户买票,那么由于网络延迟的存在会使得多个用户买票成功,这个时候就需要对买票的代码加锁。
# 假设车票的数量num存储在一个叫ticket的json文件中
# 且此时文件中余票数量为1
from multiprocessing import Process
import json
import time
def buy_ticket(i): # 买票
# 查询余票
with open(‘ticket‘,mode=‘r‘,encoding=‘utf-8‘) as f:
ticket = json.load(f)
time.sleep(0.1) # 模拟网络延时
if ticket[‘num‘]>0:
ticket[‘num‘] -= 1
print(f‘{i}购票成功‘)
else:
print("余票不足")
with open(‘ticket‘,mode=‘w‘,encoding=‘utf-8‘) as f:
json.dump(ticket,f) # 修改余票信息
if __name__==‘__main__‘:
# 假设有几个人同时买票
for i in range(5):
Process(target=buy_ticket,args=(i,)).start()
"""
0购票成功
1购票成功
2购票成功
3购票成功
4购票成功
"""
# 在余票是1的情况下,五个人同时购票成功,显然这是有缺陷的
所以这时候需要一个程序来控制同一时间进行买票的客户端个数,这个程序就是锁。
# 假设车票的数量num存储在一个叫ticket的json文件中
# 且此时文件中余票数量为1
from multiprocessing import Process
import json
import time
def buy_ticket(i): # 买票
# 查询余票
with open(‘ticket‘,mode=‘r‘,encoding=‘utf-8‘) as f:
ticket = json.load(f)
time.sleep(0.1) # 模拟网络延时
if ticket[‘num‘]>0:
ticket[‘num‘] -= 1
print(f‘{i}购票成功‘)
else:
print("余票不足")
with open(‘ticket‘,mode=‘w‘,encoding=‘utf-8‘) as f:
json.dump(ticket,f) # 修改余票信息
def get_ticket(i,lock):
lock.acquire() # 拿到钥匙
buy_ticket(i)
lock.release() # 归还钥匙
if __name__==‘__main__‘:
# 假设有几个人同时买票
# 设置锁
lock = Lock()
for i in range(5):
Process(target=get_ticket,args=(i,lock)).start()
"""
0购票成功
余票不足
余票不足
余票不足
余票不足
"""
这里锁的作用是控制lock.acquire()
和lock.release()
之间的代码同一时间只有一个进程执行。它的作用机制是将之间的代码上锁,同时钥匙也在旁边但是只有一把。同一时间只能一个进程拿钥匙开锁进入并关门,直到执行完再出门上锁还钥匙,这样就保证了同一时间只能一个进程执行。
# 上面代码中的上锁过程需要作如下优化
"""
lock.acquire() # 拿到钥匙
buy_ticket(i)
lock.release() # 归还钥匙
"""
# 修改为:
with lock:
buy_ticket(i)
# 因为如果buy_ticket(i)执行过程中程序报错,那么会因为没有执行release这个归还钥匙的代码而导致钥匙丢失
# 而使用with则能够克服这个异常情况
使用锁的时候,没有被锁住的代码仍然会被进程并发执行。上述这种锁称为互斥锁,在同一个进程中不能acquire多次,因为钥匙只有一把,只有第一个acquire会被执行。
进程之间的相互通信(IPC,Inter Process Communication)
基于文件:同一台机器上的多个进程之间通信
# 父进程和子进程之间通信
from multiprocessing import Queue,Process
def func(q):
q.put(‘hello‘)
if __name__==‘__main__‘:
q = Queue() # 只有队列可以做到传输,其他的数据类型都不行
p = Process(target=func,args=(q,)) # 子进程传输消息
p.start()
print(q.get()) # 父进程尝试接收
# hello
基于网络:同一台机器或多台机器上的多进程通信
生产者消费者模型
本质:让生产数据和消费数据的效率达到平衡并且最大化的模型。
# 写一个最最简单的生产者消费者模型
from multiprocessing import Process
def consumer(q): # 消费者:通常取到数据后还要对数据进行处理
for i in range(5):
print(q.get())
def producer(q): # 生产者:通常在传数据之前要通过某些代码获取数据
for i in range(5):
q.put(i)
if __name__==‘__main__‘:
q = Queue()
c1 = Process(target=consumer,args=(q,))
p1 = Process(target=producer,args=(q,))
c1.start()
p1.start()
"""
0
1
2
3
4
"""
原文:https://www.cnblogs.com/20-03-14/p/12680690.html