多进程编程
程序员文章站
2022-06-19 13:26:27
...
多进程编程
概念
程序: 计算机中存储的二进制代码
进程: 计算机中运行的程序
多进程: 多个进程同时运行
进程的创建
Linux环境下执行
实例:
import os
import time
def sing():
for v in range(3):
print("我在唱歌")
time.sleep(1)
def dance():
for v in range(3):
print("我在跳舞")
time.sleep(1.1)
time_start = time.time()
# 创建多个进程
pid = os.fork()
# print(f'子进程{os.getpid()},父进程{os.getppid()}')
if pid == 0:
# 子进程执行
sing()
else:
# 父进程执行
dance()
time_end = time.time()
# 如何父进程先结束,子进程就不再执行
print(f"耗费{time_end-time_start}")
getpid() 获取当前进程的id,getppid()获取父进程的id
子进程的id永远为0,父进程的id永远大于0
os.fork() 是创建多个进程
多进程修改全局变量
import os
num = 0
pid = os.fork()
if pid == 0:
num += 1
print("当前{}".format(num))
else:
num += 1
print("当前{}".format(num))
# 结果都为1
创建多进程后,子进程会复制父进程的内存空间,进程执行时是修改的自己的内存空间,输出的也是自己内存中的值
多次fork
import os
pid = os.fork()
if pid == 0:
print("hello")
else:
print("hello")
pid = os.fork()
if pid == 0:
print("hello")
else:
print("hello")
# 执行6次
python多进程编程
实例:
from multiprocessing import Process
import os
import time
def sing(num, name):
print(f"当前pid:{os.getpid()}")
for v in range(num):
print(f"{name}在唱歌")
time.sleep(1)
def dance(num, name):
print(f"当前pid:{os.getpid()}")
for v in range(num):
print(f"{name}在跳舞")
time.sleep(1.1)
def main():
time_start = time.time()
# 创建一个子进程实例
pro1 = Process(target=sing, args=(3,), kwargs={"name": "libai"})
# 开始一个子进程
print(pro1.is_alive()) # False
pro1.start()
# 进程是否还在执行
print(pro1.is_alive()) # True
pro2 = Process(target=dance, args=(3,), kwargs={"name": "dufu"})
pro2.start()
# 等待pro1结束后在执行后面代码
pro1.join()
# 等待pro2结束后在执行后面代码
pro2.join()
print(pro1.is_alive()) # False
print(f"当前pid:{os.getpid()},耗费{time.time()-time_start}")
if __name__ == '__main__':
main()
Process常用参数和方法
target:表示这个进程实例所调用对象
args:表示调用对象的位置参数元组
kwargs:表示调用对象的关键字参数字典
start():启动进程实例(创建子进程)
is_alive():判断进程实例是否还在执行
join([timeout]):是否等待进程实例执行结束,或等待多少秒
继承类Process
from multiprocessing import Process
class Proce(Process):
def __init__(self, name):
# 在初始化时要调用一下父类的初始方法
#因为Process类本身也有__init__方法,这个子类相当于重写了这个方法,
#但这样就会带来一个问题,我们并没有完全的初始化一个Process类,所以就不能使用从这个类继承的一些方法和属性,
#最好的方法就是将继承类本身传递给Process.__init__方法,完成这些初始化操作
# Process.__init__()
super(Proce, self).__init__()
self.name = name
def run(self):
print(f"进程:{self.name}")
def main():
p1 = Proce("子进程")
# 调用start方法时会自动调用run方法
p1.start()
p1.join()
print('父进程')
if __name__ == '__main__':
main()
进程池
import os
from multiprocessing import Pool
def job(args):
print("当前进程{},{}".format(os.getpid(), args))
time.sleep(random.random() * 3)
# 定义进程池
pool = Pool(4)
for v in range(10):
# 调用方法
pool.apply_async(job, (v,))
# 关闭进程池
pool.close()
# 等待进程结束
pool.join()
进程间的通信
queue的使用
Queue.qsize(): 返回当前队列包含的消息数量;
Queue.empty(): 如果队列为空,返回True,反之False ;
Queue.full(): 如果队列满了,返回True,反之False;
Queue.put(): 存储值
Queue.get(): 取值
实例:
from multiprocessing import Process, Queue
def write(queue):
# 将数据写入队列
for v in ["a", "b", "c", "d"]:
queue.put(v)
def read(queue):
# 获取队列里的值
while True:
if not queue.empty():
print(queue.get())
else:
break
def main():
# 创建一个队列
queue = Queue()
p = Process(target=write, args=(queue,))
p.start()
p.join()
p2 = Process(target=read, args=(queue,))
p2.start()
p2.join()
print("结束任务")
if __name__ == '__main__':
main()
进程扩展
孤儿进程:父进程结束了,子进程还没结束
僵尸进程:子进程结束了,而父进程不能收回子进程的内存空间
查看僵尸进程: ps -ef |grep “def”
守护进程:父进程结束了,子进程还没结束,子进程被1号进程接收,不能够直接退出子进程
转载于:https://my.oschina.net/u/4161332/blog/3072248
下一篇: 多进程的编程