(十)并发编辑----(一)
目录
10.1multiprocess.process模块
a.Process模块
Process([group [, target [, name [, args [, kwargs]]]]])
1 group参数未使用,值始终为None
2 target表示调用对象,即子进程要执行的任务
3 args表示调用对象的位置参数元组(1,)
4 kwargs表示调用对象的字典
5 name为子进程的名称
方法介绍:
1 p.start():启动进程,并调用该子进程中的p.run()
2 p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法
3 p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
4 p.is_alive():如果p仍然运行,返回True
5 p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程
属性介绍:
1 p.start():启动进程,并调用该子进程中的p.run()
2 p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法
3 p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
4 p.is_alive():如果p仍然运行,返回True
5 p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程
b.使用Process模块创建一个新进程
from multiprocessing import Process
import time
def son_process(a):
time.sleep(3)
print('子进程', a)
if __name__ == '__main__':
p = Process(target=son_process, args=(1,))
p.start()
print('主进程')
# join() 异步的程序改为同步
import time
from multiprocessing import Process
def func(arg1,arg2):
print('*'*arg1)
time.sleep(5)
print('*'*arg2)
if __name__ == '__main__':
p = Process(target=func,args=(10,20))
p.start()
print('hahahaha')
p.join() # 是感知一个子进程的结束,将异步的程序改为同步
print('====== : 运行完了')
'''
hahahaha
**********
********************
====== : 运行完了
''''
#join() 进阶
import os
import time
from multiprocessing import Process
def func(filename,content):
with open(filename,'w') as f:
f.write(content*10*'*')
if __name__ == '__main__':
p_lst = []
for i in range(3):
p = Process(target=func,args=('info%s'%i,0))
p_lst.append(p)
p.start()
for p in p_lst: #[p.join() for p in p_lst]
p.join() # 之前的所有进程必须在这里都执行完才能执行下面的代码
print([i for i in os.walk(r'D:\python学习笔记\day037')])
c.通过继承Process类开启进程
自定义类 继承Process类,必须实现一个run方法,run方法中是在子进程中执行的代码
import os
from multiprocessing import Process
class MyProcess(Process):
def __init__(self,arg1,arg2):
super().__init__()
self.arg1 = arg1
self.arg2 = arg2
def run(self):
print(self.pid)
print(self.name)
print(self.arg1)
print(self.arg2)
if __name__ == '__main__':
p1 = MyProcess(1,2)
p1.start()
p2 = MyProcess(3,4)
p2.start()
d.守护进程
进程之间是互相独立的,主进程代码运行结束,守护进程随即终止
守护进程会随着主进程的代码执行完毕而结束
daemon一定要在start()前面
在主进程内结束一个子进程 p.terminate(),结束一个进程不是在执行方法之后立即生效,需要一个操作系统响应的过程
# 子进程 -- > 守护进程
import time
from multiprocessing import Process
def func():
while True:
time.sleep(0.2)
print('我还活着')
def func2():
print('in func2 start')
time.sleep(8)
print('in func2 finished')
if __name__ == '__main__':
p = Process(target=func)
p.daemon = True # 设置子进程为守护进程 daemon一定要在start()前面
p.start()
p2 = Process(target=func2)
p2.start()
p2.terminate() # 结束一个子进程
time.sleep(1)
print(p2.is_alive()) # 检验一个进程是否还活着
print(p2.name)
e.使用多进程实现socket服务端的并发效果
#server
import socket
from multiprocessing import Process
def serve(conn):
ret = '你好'.encode('utf-8')
conn.send(ret)
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()
try:
while True:
conn, addr = sk.accept()
p = Process(target=serve, args=(conn,))
p.start()
finally:
sk.close()
#client
import socket
sk = socket.socket()
sk.connect(('127.0.0.1', 8080))
msg = sk.recv(1024).decode('utf-8')
print(msg)
msg2 = input('>>>').encode('utf-8')
sk.send(msg2)
sk.close()
10.2进程同步(multiprocess.Lock)
加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改
# 火车票{"ticket": 2}
import json
import time
from multiprocessing import Process
from multiprocessing import Lock
def show(i):
with open('ticket') as f:
dic = json.load(f)
print('余票: %s'%dic['ticket'])
def buy_ticket(i,lock):
lock.acquire() #拿钥匙进门
with open('ticket') as f:
dic = json.load(f)
time.sleep(0.1)
if dic['ticket'] > 0 :
dic['ticket'] -= 1
print('\033[32m%s买到票了\033[0m'%i)
else:
print('\033[31m%s没买到票\033[0m'%i)
time.sleep(0.1)
with open('ticket','w') as f:
json.dump(dic,f)
lock.release() # 还钥匙
if __name__ == '__main__':
for i in range(4):
p = Process(target=show,args=(i,))
p.start()
lock = Lock()
for i in range(4):
p = Process(target=buy_ticket, args=(i,lock))
p.start()
'''
余票: 2
余票: 2
余票: 2
余票: 2
3买到票了
0买到票了
2没买到票
1没买到票
'''