1,进程之间不共享全局变量
创建子进程其实是对主进程进行拷贝,进程之间互相独立,访问的全局变量不是同一个,所以进程之间不共享全局变量
2,主进程会等待所有的子进程执行完成程序再退出
import multiprocessing
import time
# 测试子进程是否执行完成以后主进程才能退出
def work():
for i in range(10):
print("工作中...")
time.sleep(0.2)
if __name__ == '__main__':
# 创建子进程
work_process = multiprocessing.Process(target=work)
work_process.start()
# 让主进程等待1秒钟
time.sleep(1)
print("主进程执行完成了啦")
工作中...
工作中...
工作中...
工作中...
工作中...
主进程执行完成了啦
工作中...
工作中...
工作中...
工作中...
工作中...
2.1,销毁子进程代码(类似于线程守护)
方法一:
设置守护主进程,主进程退出后子进程直接销毁,不再执行子进程中的代码
work_process.daemon = True
方法二:
让子进程直接销毁,表示终止执行, 主进程退出之前,把所有的子进程直接销毁就可以了
work_process.terminate()
3,进程之间通信
3.1 可以使用multiprocessing模块的Quess实现多进程之间的数据传递,Quess本身是一个消息队列程序,首先用一个小实例来演示Quess的工作原理
# 创建消息队列, 3:表示队列中最大消息个数
queue = multiprocessing.Queue(3)
# 放入数据
queue.put(数据) 会进行等待
queue.put_nowait(数据) 不会进行等待
1,队列中可以放入任意数据类型
2,如果队列满了,需要等待队列有空闲位置才能放入数据,否则一直等待
3,如果队列满了,不等待的话,放入不成功会直接崩溃
# 查看队列的个数
print(queue.qsize())
# 获取数据
queue.get()
queue.get_nowait()
1,如果队列空了,在屈指需要等待,只有队列有值以后才能获取队列中的数据
2,如果不等待队列有值,队列中为空值会直接报错
注意点
初始化对象的时候,Queue()没有上线的时候,说明可接受的消息没有数量的上限(知道内存的尽头) Queue.empty() 如果队列为空,返回值为true 反之为false; Queue.full() 如果队列满了,返回true,反之为flase; Queue.get([block[,timeout]]) 从队列中获取信息,然后从队列中移除,block默认值为true;
block为默认值
1,如果没有设置timeout,程序会阻塞程序会停在读取状态,直到从消息队列中读取到信息,如果设置了时间,等待时间到了,还没有读取到信息,会抛出Queue.Empty异常
2,没有设置timeout,消息队列没有空间可写入程序会阻塞,直到消息队列腾出空间为止,如果设置timeout,会等待timeout秒,则会抛出Queue.Full异常
block为flase
1,消息队列为空也就是没有空间可以写入的时候,会立即抛出Queue.Empty异常
2,消息队列为空也就是说没有消息可以读取,会立即抛出Queue.Empty异常
Queue.get_nowait() = Queue.get(flase)
Queue.put_nowait(item) = Queue.put(item,False)
3.2 怎么理解
理论性的东西,能记住除非天天用,总结才是最关键,上面解释说到的,无非就是一个读取等待和写入等待,处理不好就会是Queue.Empty的异常,默认情况下我们使用true,不要尝试去使用Flase,会让你很头疼
3.3 怎么使用
import multiprocessing
import time
# 写入数据
def write_data(queue):
for i in range(10):
if queue.full():
print("队列满了")
break
queue.put(i)
time.sleep(0.2)
print(i)
# 读取数据
def read_data(queue):
while True:
# 加入数据从队列取完了,那么跳出循环
if queue.qsize() == 0:
print("队列空了")
break
value = queue.get()
print(value)
if __name__ == '__main__':
# 创建消息队列
queue = multiprocessing.Queue(5)
# 创建写入数据的进程
write_process = multiprocessing.Process(target=write_data, args=(queue,))
# 创建读取数据的进程
read_process = multiprocessing.Process(target=read_data, args=(queue,))
# 启动进程
write_process.start()
# 主进程等待写入进程执行完成以后代码再继续往下执行
write_process.join()
read_process.start()
0
1
2
3
4
队列满了
0
1
2
3
4
队列空了
小结
我们在使用队列的时候,放入数据需要等待一下(睡眠),判断队列状态一般不使用Queue.Empty() 这个方法容易不准确,使用Queue.Full() 放入数据用put(),取出数据用get()