多进程概述
多进程代码:
from multiprocessing import Process
方法:
进程对象.start()——开启一个子进程
进程对象.join()——感知一个子进程的结束
进程对象.terminamte()——结束一个子进程
进程对象.is_alive()——查看某个子进程是否还在运行
属性:
进程对象.name——进程名
进程对象.pid——进程号
进程对象.daemon——值为True时,标识新的子进程是一个守护进程
守护进程:
守护进程:随着主进程代码的执行结束而结束
必须要写在start之前
加锁:
from multiprocessing import Lock
l = Lock()
l.acquire() # 拿钥匙
# 会造成数据不安全的操作
l.release() # 还钥匙
创建进程有两种方法:
1.使用process模块创建进程
在一个python进程中开启子进程,start方法和并发效果。
from multiprocessing import Process import os import time def fun(arg1,arg2): print('*'*arg1) time.sleep(3) print('*'*arg2) if __name__ == '__main__': p_lst=[] for i in range(10): p = Process(target=fun,args=(i+1,i+5)) p_lst.append(p) p.start() [p.join() for p in p_lst] print('执行完毕!!!')
2.继承Process类的形式开启进程
需要注意的点:
如果需要传参,那么在类中定义init方法是记得写入super().__init__()来继承父类中其他属性,否则会报错
from multiprocessing import Process import os class MyProcess(Process): def __init__(self,name,age): super().__init__() self.name = name self.age = age def run(self): print(111) print(self.name) print(self.age) if __name__ == '__main__': p = MyProcess('Mr.Feng',18) p.start()
进程之间的数据隔离
from multiprocessing import Process import os def func(): global n n = 0 print('pid : {}'.format(os.getpid()),n) if __name__ == '__main__': n = 100 p = Process(target=func) p.start() p.join() print(os.getpid(),n) # 几个数据之间如果不用特殊方法无法实现变量共享
通过多进程实现server并发
import socket from multiprocessing import Process def server(conn): info = '你好'.encode('utf-8') conn.send(info) msg = conn.recv(1024).decode('utf-8') print(msg) conn.close() if __name__ == '__main__': sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen(0) while True: conn, addr = sk.accept() p = Process(target=server,args=(conn,)) p.start() sk.close()
import socket sk = socket.socket() sk.connect(('127.0.0.1',8080)) while True: msg = sk.recv(1024).decode('utf-8') print(msg) info = input('>>') if info == 'q':break sk.send(info.encode('utf-8')) sk.close()
import socket sk = socket.socket() sk.connect(('127.0.0.1',8080)) while True: msg = sk.recv(1024).decode('utf-8') print(msg) info = input('>>') if info == 'q':break sk.send(info.encode('utf-8')) sk.close()
守护进程
from multiprocessing import Process import time def func(): while True: time.sleep(0.2) print('我还活着') def func2(): print('in func2 start') time.sleep(8) if __name__ == '__main__': p = Process(target=func) p.daemon = True # 守护进程:主进程结束,子进程结束 p.start() p1 = Process(target=func2) p1.start() i = 0 while i<5: print('我是socketserver') time.sleep(1) i+=1 # 守护进程会随着主进程的代码结束而结束 # 在主进程内结束一个子进程p.terminate() # 结束一个进程不是在执行方法之后立即失效,需要一个操作系统响应的过程 # 检验一个进程是否还活着的状态p.is_alive() # p.name p.pid 这个进程的名字和进程号
进程锁
在修改文件时必须加设备锁
from multiprocessing import Process import json import time from multiprocessing import Lock def show(arg): with open('tiket') as f: dic = json.load(f) print('余票:{} '.format(dic['ticket']),arg) def buy(arg,lock): lock.acquire() # 拿到钥匙进入程序 with open('tiket') as f: dic = json.load(f) time.sleep(0.1) if dic['ticket']>0: dic['ticket'] -= 1 print('\033[32m{}买到票了\033[0m'.format(arg)) else: print('\033[31m{}没买到票\033[0m'.format(arg)) with open('tiket','w') as f: json.dump(dic,f) lock.release() # 归还钥匙 if __name__ == '__main__': for i in range(10): p = Process(target=show,args=(i,)) p.start() lock = Lock() for i in range(10): p = Process(target=buy,args=(i,lock)) p.start()
信号量
在规定能同事访问某段代码的进程数
from multiprocessing import Process from multiprocessing import Semaphore import time import random def ktv(i,sem): sem.acquire() print('%s走进KTV' % i) time.sleep(random.randint(10,20)) sem.release() if __name__ == '__main__': sem = Semaphore(4) for i in range(20): p = Process(target=ktv,args=(i,sem)) p.start()