本文阅读时长大约为8分钟。
❈
进程
❈
今日思维导图
练习代码
进程实现多任务
import multiprocessing
import threading
def test1(num):
for i in range(num):
print("---test1 %d" % i)
def test2(num):
for i in range(num):
print("---test2 %d" % i)
def main():
"""创建子进程只需要把库换成 multiprocessing.Proess 即可"""
# t1 = threading.Thread(target=test1, args=(5,))
# t2 = threading.Thread(target=test2, args=(10,))
p1 = multiprocessing.Process(target=test1, args=(5,))
p2 = multiprocessing.Process(target=test2, args=(10,))
p1.start()
p2.start()
if __name__ == '__main__':
main()
获取进程的pid
import multiprocessing
import os
import time
"""
获取进程的pid
os.getpid 可以获取当前进程的进程号
os.getppid 可以获取当前进程父进程的进程号
"""
def test():
while True:
print("--当前进程是 %s ,父进程是 %s " % (os.getpid(), os.getppid()))
time.sleep(1)
def main():
# 创建进程
p = multiprocessing.Process(target=test)
p.start()
print("主程序进程是 %s" % os.getpid())
pass
if __name__ == '__main__':
main()
进程传递参数
import multiprocessing
"""
Process 传递的参数可以是多值参数
*args: 代表多值元组
**kwargs: 打包多值字典
"""
def test(a, *args, **kwargs):
print(a)
for num in args:
print(num)
print(kwargs)
def main():
p = multiprocessing.Process(target=test, args=(1, 2, 3, 4, 5), kwargs={"name": "xiaohei"})
p.start()
if __name__ == '__main__':
main()
进程之间不共享全局变量
import os
import time
import multiprocessing
"""
Process 语法结构如下:
Process([group[, target[, name[,args][, kwargs]]]])
target: 如果传递了函数的引用,可以认为这个子程序就执行这里的代码
args: 给 target 指定的函数传递的参数,已元组的方式传递
kwargs:给 target 指定的函数传递命名参数, 字典
name: 给进程设定一个名字, 可以不设定
group: 指定进程组,大多数情况用不到
Process 创建的实例对象的常用方法:
start(): 启动子进程实例(创建子进程)
is_alive(): 判断进程子进程是否还在活着
join([timeout]): 是否等待子进程执行完毕,或者等待多少秒
terminate: 不管任务是否完成,立即终止子进程
Process 创建的实例对象的常用属性:
name: 当前进程的别名, 默认为 Process-N, N为从 1 开始递增的整数
pid:当前进程的 pid (进程号) ppid(父进程号)
"""
# 指定一个全局变量
nums = [1, 2, 3, 4]
def test():
nums.append(5)
print("--在 test 中 nums = %s" % nums)
time.sleep(3)
def test2():
print("-- 在 test2 中 nums = %s" % nums)
def main():
print("主程序进程是 %s, 主程序父进程是 %s" % (os.getpid(), os.getppid()))
# 创建进程
p = multiprocessing.Process(target=test)
p.start() # 启动进程
p.join(1) # 等待子进程执行完毕, 可以指定等待的时间
p2 = multiprocessing.Process(target=test2)
p2.start()
if __name__ == '__main__':
main()
多进程之间通过 Queue 队列来共享数据
import multiprocessing
"""
一个进程向队列 Queue 写入数据,另一个进程从队列中获取数据
Queue.put(): 向队列中写入数据
Queue.qsize(): 返回当前队列包含的消息数量
Queue.empty(): 如果队列为空,返回 True,反之返回 False
Queue.full(): 如果队列满了,返回 True, 反之 False
Queue.get([block[,timeout]]): 获取队列中的一条消息,然后将其从队列中移除
"""
def test1(q):
"""下载数据"""
# 模拟从网上下载数据
data = [1, 2, 3, 4]
for temp in data:
q.put(temp) # 写入数据
print("下载完毕并存入队列中")
def test2(q):
"""解析数据"""
dw_data = []
while True:
data = q.get() # 取出并移除数据
dw_data.append(data)
if q.empty(): # 如果队列为空,就退出循环
break
print(dw_data)
print("数据分析完毕")
def main():
# 创建队列
q = multiprocessing.Queue()
# 创建进程
p1 = multiprocessing.Process(target=test1, args=(q,))
p2 = multiprocessing.Process(target=test2, args=(q,))
p1.start()
p2.start()
if __name__ == '__main__':
main()
进程池
from multiprocessing import Pool
import time
import os
import random
def test(i):
t_start = time.time() # 记录程序开始的时间
print("%s 开始执行,进程号是 %d" % (i, os.getpid()))
time.sleep(random.random() * 2) # random.random 会随机生成0-1之间的浮点数
t_end = time.time() # 记录程序结束的时间
print("%s 执行完毕,用时 %.2f 秒" % (i, (t_end - t_start)))
if __name__ == '__main__':
try:
po = Pool(3) # 定义一个进程池,最大进程数为 3
for i in range(0, 10):
# pool().apply_async(要调用的目标,(传递给目标的参数元组,))
# 每次循环都将会用空闲出来的子进程去调用目标
po.apply_async(test, (i,))
print("开始")
po.close() # 关闭进程池,关闭后 po 不在接收新的请求
po.join() # 等待 po 进程池中所有子进程执行完毕,必须放在 close 语句之后
print("结束")
except Exception as result:
print(result)
突然之间就变成了一条没有梦想的咸鱼,浑身没有了动力,莫非是太累了???,自我调节一下吧!
同志们,加油!!!
END