python 多进程
创建一个进程
1,导入模块
2,创建进程
3,启动进程运行的顺序
严格来说,进程执行没有顺序, 每个进程要去cpu获取执行权限, 随机获取
from time import sleep
#导入进程模块
from multiprocessing import Process
def eat(food,game):
while True:
print('小天才喜欢吃 %s ' % food)
print('小天才喜欢玩 %s' % game)
sleep(1)
def drink(name='water'):
while True:
print('小天才喜欢喝 %s' % name)
sleep(1)
if __name__ == '__main__':
# args Arguments 缩写,单词的意思就是参数
# 参数1 target指定新进程执行的函数,后面不加括号
# 方法(函数)如果后面带有括号,代表执行这个函数
# 参数2 args 指定传递给子进程函数的参数 ,参数需要用元组包装
#创建
eat_process = Process(target=eat,args=('麻辣烫6块的','亡者农药'))
#启动
eat_process.start()
drink_process = Process(target=drink,kwargs={
'name':'红牛'})
drink_process.start()
进程超时
线程锁超时,我只等你多长时间,过了时间,我就不等你了,我就继续
父进程等待子进程的时间,子进程运行完在执行父进程
如果父进程等待的时间小于子进程运行的时间,不管子进程,先运行父进程,再运行子进程
def eat():
print('子进程启动')
sleep(10)
print('子进程任务完成')
if __name__ == '__main__':
print('父进程启动')
eat_process = Process(target=eat)
eat_process.start()
# timeout 超时,父进程等待子进程的时间节点
# 让父进程等待子进程结束再执行父进程,当子进程结束后,才会执行join后面的方法
eat_process.join(timeout=3)
print('父进程任务完成')
变量的作用域
每个进程都有独立的内存空间
在父进程创建子进程的时候,如果子进程使用了父进程中的变量,
那么子进程会将使用的变量复制一份放到自己的内存中
多进程
默认从上向下一条线式执行的程序,同步执行的
主进程调用子进程启动后,不再关注子进程的执行,直接继续执行自己的逻辑进程启动数量要选择一个最优的点
程序效率最高的时候,进程数和CPU的核心数一样多
进程池 Pool
我们可以将进程放到进程池中去执行
如果我们创建了一个8个进程的进程池,当我们有多于8个进程放入进程池的时候
并行执行8个进程,按照放入顺序,多于8个的部分进行排队
常用的两种数据结构
栈 先进后出
队列 先进先出
join之后就不能向进程池中继续添加进程了
进程池调用join,是表示等待子进程都结束后,在调用父进程的代码
再调用join之前,需要调用close方法,调用close之后的父进程不能再添加子进程了
from multiprocessing import Process,Pool
from time import sleep
def say_hello(name):
print('Hello %s' % name)
sleep(1)
print('打招呼完毕')
if __name__ == '__main__':
# 声名一个进程池,,默认是cpu核心数
pp = Pool(4)
for i in range(10):
# 向进程池中添加进程
pp.apply_async(func=say_hello,args=('小强 %d' % i,))
pp.close()
pp.join()
通讯管道
实现两个进程的通信,可以快捷使用管道来实现
Pipe
创建两个进程,由进程A给进程B发消息,由进程B给进程A发消息
对列实现多进程
import os
from multiprocessing import Queue, Process
# python中的命名有点杂
from random import random
from time import sleep
def child_send_to_queue(queue):
# 数据的获取,将数据存入队列中 random [0-1)
sleep_time = int(random() * 5 + 5)
sleep(sleep_time)
# 用睡眠模拟 数据获取(从网上下载下来的,数据从数据库中查找出来,或者从文件中查找出来)
# os.getpid() 获取当前进程的id, 在哪一个进程中执行,就获取哪一个进程的id
# 进程不是先创建 就一定先创建完成并执行
print('%d 睡了 %d 秒' % (os.getpid(),sleep_time))
queue.put(sleep_time)
if __name__ == '__main__':
# 查看文档 请去 https://www.python.org/ 右击 翻译为中文
# 初始化数据,分配任务,获取数据 -1 代表无限大
# PID process id 进程ID,每个进程有一个号码,号码唯一
message_queue = Queue()
# 分配任务
for i in range(10):
p = Process(target=child_send_to_queue,args=(message_queue,))
p.start()
# 不断获取数据
while True:
# 不断从队列中取出数据
if message_queue.empty():
print('对列没有数据')
sleep(0.2)
else:
print(message_queue.get())
# 睡眠方便观察,避免直接的死循环
sleep(0.2)
还没有评论,来说两句吧...