Process(group , target , name , args , kwargs),由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)
强调: 1. 需要使用关键字的方式来指定参数 2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号 参数介绍: 1 group参数未使用,值始终为None 2 target表示调用对象,即子进程要执行的任务 3 args表示调用对象的位置参数元组,args=(1,2,'kkk',) 4 kwargs表示调用对象的字典,kwargs={'name':'kkk','age':18} 5 name为子进程的名称
join方法
进程间是相互隔离的
1进程的创建# encoding=utf-8
# 开进程的方法一:
import time
import random
from multiprocessing import Process
def piao(name):
print('%s piaoing' % name)
time.sleep(random.randrange(1, 5))
print('%s piao end' % name)
if __name__ == '__main__':
p1 = Process(target=piao, args=('kkk',)) # 必须加,号
p2 = Process(target=piao, args=('ttt',))
p3 = Process(target=piao, args=('aaa',))
p4 = Process(target=piao, args=('bbb',))
p1.start()
p2.start()
p3.start()
p4.start()
p1.join()#实现与下面代码的同步
p2.join()
p3.join()
p4.join()
print('===========主线程===========')
# 以下代码强制同步,拖慢了程序的运行效率
for i in range(1,4):
p=Process(target=piao,args=(f'进程{i}',))
p.start()
p.join()
print('===========主线程===========')
#修改为:
list_process=[]
for i in range(1,4):
p=Process(target=piao,args=(f'进程{i}',))
p.start()
list_process.append(p)
for p in list_process:
p.join()
print('===========主线程===========')
# 开进程的方法二:
import time
import random
from multiprocessing import Process
class Piao(Process):
def __init__(self, name):
super().__init__()
self.name = name
def run(self):
print('%s piaoing' % self.name)
time.sleep(random.randrange(1, 5))
print('%s piao end' % self.name)
if __name__ == '__main__':
p1 = Piao('ttt')
p2 = Piao('aaa')
p3 = Piao('bbb')
p4 = Piao('ccc')
p1.start() # start会自动调用run
p2.start()
p3.start()
p4.start()
print('===========主线程===========')
2进程其他方法
进程PID(进程的ID号)的查看:Windows系统:(1)tasklist:查看所有进程 (2)tasklist |findstr PID:查看单个进程
import os from multiprocessing import current_process #获取当前进程的ID os.getpid() current_process().pid #获取父进程的ID os.getppid() p.terminate()#终止当前代码的运行 print(p.is_alive())#判断当前代码是否存活3守护进程
#直接在p.start的上方加上下面的代码,就可以将子进程设置为守护进程,在主进程结束之后,守护进程也会结束 p.daemon=True p.start
互斥锁:牺牲效率,保证数据安全,但是不要轻易使用,只在需要保存数据的时候使用。一般不会涉及到直接写Lock相关的代码,都是利用其他人封装好的代码
#文件db的内容为:{"count":1}
#注意一定要用双引号,不然json无法识别
from multiprocessing import Process,Lock
import time,json,random
def search():
dic=json.load(open('db'))
print(' 33[43m剩余票数%s 33[0m' %dic['count'])
def get():
dic=json.load(open('db'))
time.sleep(random.random()) # 模拟读数据的网络延迟
if dic['count'] >0:
dic['count']-=1
time.sleep(random.random()) # 模拟写数据的网络延迟
json.dump(dic,open('db','w'))
print(' 33[32m购票成功 33[0m')
else:
print(' 33[31m购票失败 33[0m')
def task(lock):
search()
lock.acquire() # 将买票这一环节由并发变成了串行,牺牲了运行效率但是保证了数据的安全
get()
lock.release()
if __name__ == '__main__':
lock = Lock()
for i in range(100): # 模拟并发100个客户端抢票
p=Process(target=task,args=(lock,))
p.start()
4队列:代码实现
from multiprocessing import Queue
q=Queue(3) # 创建一个最大只能容纳3个数据的队列
"""
常用方法
put ,get ,put_nowait,get_nowait,full,empty
"""
q.put(3) # 往队列中存放数据
q.put(3)
q.put(3)
q.put(3) # 如果队列已经满了,程序就会停在这里,等待数据被别人取走,再将数据放入队列。如果队列中的数据一直不被取走,程序就会永远停在这里。
try:
q.put_nowait(3) # 可以使用put_nowait,如果队列满了不会阻塞,但是会因为队列满了而报错。
except: # 因此我们可以用一个try语句来处理这个错误。这样程序不会一直阻塞下去,但是会丢掉这个消息。
print('队列已经满了')
# 因此,我们再放入数据之前,可以先看一下队列的状态,如果已经满了,就不继续put了。
print(q.full()) # 判断队列中数据是否已存放满了
print(q.get()) # 从队列中获取数据
print(q.get())
print(q.get())
print(q.get()) # 同put方法一样,如果队列已经空了,那么继续取就会出现阻塞。
try:
q.get_nowait(3) # 可以使用get_nowait,如果队列满了不会阻塞,但是会因为没取到值而报错。
except: # 因此我们可以用一个try语句来处理这个错误。这样程序不会一直阻塞下去。
print('队列已经空了')
print(q.empty()) # 判断队列中数据是否已经被全部取出
利用队列实现进程间通信(IPC),可以简单的理解为一边进程存数据,另一边进程取数据,从而达到数据交互的目的
import random
from multiprocessing import Process,Queue
def put_q(q):
q.put(random.randint(1,20))
def read_q(q):
print(q.get())
if __name__ == '__main__':
q = Queue(5)
for i in range(1,6):
p=Process(target=put_q,args=(q,))
p.start()
for i in range(1,7):
p=Process(target=read_q,args=(q,))
p.start()
5消费者与生产者模型:平衡存取数据的效率问题
import random
from multiprocessing import Process,JoinableQueue
def producer(q):
for i in range(10):
q.put(random.randint(1,20))
def consumer(q):
while True:
print(q.get())
q.task_done()#告诉队列已经取出一个数据并且处理完毕
if __name__ == '__main__':
q = JoinableQueue(5)
'''内部有一个计数器,当存入一个数据,计数器加一,当执行一次q.task_done(),计数器减一'''
p=Process(target=producer,args=(q,))
p.start()
p1=Process(target=consumer,args=(q,))
p1.daemon=True
p1.start()
p.join()
q.join()#等待队列中的数据全部取出,再执行以下的代码



