一、开启进程的两种方式
方式一:
# 方式一:使用函数开启进程 from multiprocessing import Process import time def task(x): print('%s is running' % x) time.sleep(1) print('%s is done' % x) if __name__ == '__main__': # p1 = Process(target=task, args=('子进程',)) #实例化子进程 p1 = Process(target=task, kwargs={'x': '子进程'}) p1.start() # 向操作系统申请资源(内存空间,子进程pid号),然后开始执行task任务,本动作不影响主进程,主进程则会继续执行。 print('这是主进程...')
方式二:
from multiprocessing import Process import time class MyProcess(Process): def __init__(self,x): super(MyProcess,self).__init__() self.x = x def run(self): print('%s is running'%self.x) time.sleep(1) print('%s is done'%self.x) if __name__ == '__main__': p1 = MyProcess('子进程') p1.start() print('这是主进程....')
二、进程间数据是物理隔离的
# from multiprocessing import Process # import time # # x = 100 # def task(): # global x # x = 0 # print('子进程中执行x所得的值为%s'% x) # time.sleep(1) # # if __name__ == '__main__': # p1 = Process(target=task) # p1.start() # p1.join() # print('父进程中执行x所得的值为%s'% x)
from multiprocessing import Process import time # def task(n,t): # print('%s is running'% n) # time.sleep(t) # print('%s is done!'% n) # # # if __name__ == '__main__': # p1 = Process(target=task,args=('子进程%s'% 1,1)) # p2 = Process(target=task,args=('子进程%s'% 2,2)) # p3 = Process(target=task,args=('子进程%s'% 3,3)) # # start = time.time() # p1.start() # p1.join() # # p2.start() # p2.join() # # p3.start() # p3.join() # # # p1.join() # # p2.join() # # p3.join() # # stop = time.time() # print('子进程执行时间为%s'%(stop-start)) # # print('主进程....') # ''' # a 没有join的情况下,执行时间为0.008279085159301758 # b 有join的情况下,执行时间为3.011568069458008 # c 程序执行逻辑为串行时,执行时间为6.037945747375488 # '''
from multiprocessing import Process import time def task(n,t): print('%s is running'% n) time.sleep(t) print('%s is done!'% n) if __name__ == '__main__': start = time.time() p_list = [] for i in range(1,4): p = Process(target=task, args=('子进程%s'%i,i)) p_list.append(p) p.start() for j in p_list: j.join() stop = time.time() print('子程序消耗的时间合计%s'%(stop-start)) print(p_list) print('主程序...')
三、孤儿进程和僵尸进程
''' 子进程的开启所消耗的资源和时间比较长 所有的子进程在执行完毕之后,并不会立即消失,会保留进程号,进程的执行时间等,这种状态称为僵尸进程 异步:父进程没死,子进程还在运行,但是父进程不发送wait()/waitpid()给子进程---僵尸进程 紧接着,父进程死了,子进程还在运行,此时子进程就是孤儿进程,会被init进程(0)接管。(此时init会发送wait给子进程) '''
四、守护进程及一些进程的属性
from multiprocessing import Process import time import os def task(x): print('%s is running %s'%(x,os.getpid())) # time.sleep(2) print('%s is done'%x) if __name__ == '__main__': p = Process(target=task, args=('子进程',),name='自定义进程名称') p.daemon = True # 代表子进程是一个守护进程,守护的是父进程 # 释义:当父进程执行完毕之后,子进程也随之死掉(有点像皇帝死了,活着的妃子们也跟着陪葬。。。) # 所以,子进程task()就直接死了,不会打印任何信息,因为子进程开启时间较长 p.start() print('主') # print('子进程为%s'%p.pid) #获取当前进程ID # print('进程为%s'%os.getppid()) #获取父进程ID # print(p.name) #打印进程名称,默认现实process-1,若需要自定义进程名字的话,则需要在Process()中定义name='自定义' # print(p.is_alive()) #判断子进程是否存活,True/False
五、互斥锁(实际工作中,可能不是经常会使用到互斥锁,推荐使用队列)
import random from multiprocessing import Process from multiprocessing import Lock import time import json import os def check(): time.sleep(1) with open('db.txt','rt',encoding='utf-8')as f1: db_dic = json.load(f1) print('%s 查看了剩余的票数为%s'%(os.getpid(),db_dic['count'])) def get_ticket(): time.sleep(2) with open('db.txt','rt',encoding='utf-8')as f1: db_dic = json.load(f1) if db_dic['count'] > 0: # print('可以买') db_dic['count'] -= 1 time.sleep(random.randint(1,3)) with open('db.txt','wt',encoding='utf-8') as f1: json.dump(db_dic,f1) print('%s 购买成功'% os.getpid()) else: print('%s 购买失败'% os.getpid()) def task(mutex): check() #查看动作是并发的 mutex.acquire() #加锁 get_ticket() #需要串行来进行买票 mutex.release() #释放锁 if __name__ == '__main__': mutex = Lock() # 启用互斥锁 for i in range(10): p = Process(target=task,args=(mutex,)) p.start() # join: 会等待所有的子进程执行完毕, 程序变成串行的 # mutex: 互斥锁会将共享的数据操作,变成串行 虽然效率降低了,但是安全性和数据完整性提升
六、队列(推荐使用队列)
# #例1: # import time # import random # from multiprocessing import Queue # from multiprocessing import Process # # # # def producer(food, q, name): # for i in range(3): # res = '%s%s'%(food,i) # time.sleep(random.randint(1,3)) # q.put(res) # print(' 33[32;1m %s 生产了%s 33[0m'%(name,res)) # # q.put(None) # # # # # def consumer(q, name): # # while True: # res = q.get() # if res == None:break # time.sleep(random.randint(1,3)) # print('%s消费了%s'%(name,res)) # # # if __name__ == '__main__': # q = Queue() # p1 = Process(target=producer, args=('包子',q,'egon')) # p2 = Process(target=producer, args=('泔水',q,'stephen')) # p3 = Process(target=producer, args=('翔',q,'小猴')) # # # # c1 = Process(target=consumer, args=(q,'WuPeiQisb')) # c2 = Process(target=consumer, args=(q,'alex')) # # p1.start() # p2.start() # p3.start() # # c1.start() # c2.start() # # p1.join() # p2.join() # p3.join() # # q.put(None) # q.put(None) # # print('主...')
#例2: import time import random from multiprocessing import Process from multiprocessing import JoinableQueue def producer(q, name, food): for i in range(3): res = '%s%s'%(food,i) time.sleep(random.randint(1,3)) q.put(res) print('