一、进程的几个方法
from multiprocessing import Process
import os
import time
def func(arg):
print(arg)
print(12345)
time.sleep(1)
print('子进程:',os.getpid())
print('子进程的父进程') #查看子进程的父进程
print(54321)
if __name__ == '__main__':
p = Process(target=func,args=('参数',)) #注册 p是一个进程对象,还没有启动进程
p.start() #开启一个子进程
print('*'*2)
print('父进程:',os.getpid())
print('父进程的父进程:',os.getppid()) #查看父进程的父进程
输出结果:
**
父进程: 11508
父进程的父进程: 14160
子进程中的打印不显示
二、进程的生命周期
1、主进程
2、 子进程
3、开启了子进程的主进程:
(1)自己的代码如果长,等待自己的代码执行结束
(2)子进程的执行时间长,主进程会在主进程代码执行完毕后等待子进程执行完毕后,主进程才结束
三、join方法:
join
import time
from multiprocessing import Process
def func(r1,r2):
print('*'*r1)
time.sleep(2)
print('*'*r2)
if __name__ == '__main__':
p = Process(target=func,args=(10,20))
p.start()
p.join() #是感知一个进程的结束
print('end')
输出结果:
子进程中的打印不显示
end
四、进程编写的两种方式:
1、多个进程第一种方式
import time
from multiprocessing import Process
def func(r1,r2):
print('*'*r1)
time.sleep(2)
print('*'*r2)
if __name__ == '__main__':
p_list = []
for i in range(10):
p = Process(target=func,args=(10*i,20*i))
p_list.append(p)
p.start()
[p.join() for p in p_list]
print('end')
输出结果:
当所有程序执行完
end
2、多个进程第二种方式
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): #必须实现一个run方法,run方法是在子进程中执行的代码
print(os.getppid())
print(self.name) #进程名
print(self.pid) #进程号
print(self.arg1)
if __name__ == '__main__':
print('主:', os.getppid())
p1 = MyProcess(1,2)
p1.start() #自动调用run法
p2 = MyProcess(3,4)
p2.start()
@自定义类 继承Process类
输出结果:
主: 11388
子进程中的打印不显示
五、多进程之间隔离问题
from multiprocessing import Process
import os
import time
def func():
global n
n = 0
print('pid:%s'%os.getpid(),n)
time.sleep(5)
if __name__ == '__main__':
n = 100
p = Process(target=func)
p.start()
# p.join()
print(os.getppid(),n)
输出结果:
11388 0
xxxx 100
六、守护进程(子进程->守护进程)
import time
from multiprocessing import Process
def func():
while True:
time.sleep(0.5)
print("I'm fine" )
def func2():
print('func2')
time.sleep(8)
print('in func2 finsh')
if __name__ == '__main__':
p = Process(target=func)
p.daemon = True #设置子进程为守护进程
p.start()
p2 = Process(target=func2)
p2.start()
p2.terminate() #结束一个子进程
print(p.is_alive())
time.sleep(3)
print(p2.is_alive()) #检测一个进程是否还活着
(1)进程会随着主进程的代码执行完毕而结束
(2)结束一个进程不是在执行方法之后立即生效,需要一个操作系统响应的过程
七、进程锁
火车票问题
import json
import time
from multiprocessing import Process,Lock
def buy_ticket(i):
lock.acquire() #拿钥匙进门
with open('ticket') as f:
dic = json.load(f)
time.sleep(0.5)
if dic['ticket'] > 0:
dic['ticket'] -= 1
print('%s买到了'%i)
else:
print('%s没买到'%i)
time.sleep(0.5)
with open('ticket','w') as f:
json.dump(dic,f)
lock.release() #还钥匙
def show():
with open('ticket',encoding='utf-8') as f:
ret = json.load(f)
print('余票%s'%ret['ticket'])
if __name__ == '__main__':
for i in range(10):
p = Process(target=show)
p.start()
lock = Lock()
for i in range(10):
p = Process(target=buy_ticket,args=(i,))
p.start()
八、复习
1、多进程代码(socket)
server端:
import socket
from multiprocessing import Process
def servers(conn):
reg = '你好'.encode('utf-8')
conn.send(reg)
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(5)
while True:
conn, addr = sk.accept()
p = Process(target=servers, args=(conn,))
p.start()
sk.close()
client端:(可连接多个用户)
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',8080))
ret = sk.recv(1024).decode('utf-8')
print(ret)
msg = input('>>').encode('utf-8')
sk.send(msg)
sk.close()
2、方法
(1)进程对象.start()
开启一个子进程
(2)进程对象.join()
感知一个进程的结束
(3)进程对象.terminate()
结束一个子进程
(4)进程对象.is_alive()
查看某个进程是否还在运行
3、属性
(1) 进程对象.name
进程名
(2)进程对象.pid
进程号
(3)进程对象.daemon
值为True的时候,表示新的子进程是一个守护进守护进程,随着主进程代码的执行结束而结束,一定在start之成设置。