1. 进程介绍
进程:正在执行的程序
程序:没有执行的代码,是一个静态的状态
多进程入门使用简介:
导入模块 multiprocessing
调用方法 multiprocessing.Process(target = 目标函数名)
import multiprocessing
import threading
import time
def demo1():
while True:
print('--1--')
time.sleep(1)
def demo2():
while True:
print('--2--')
time.sleep(1)
def main():
# 多线程
# t1 = threading.Thread(target=demo1)
# t2 = threading.Thread(target=demo2)
#
# t1.start()
# t2.start()
# 多进程
p1 = multiprocessing.Process(target=demo1)
p2 = multiprocessing.Process(target=demo2)
p1.start()
p2.start()
# 传统方式
# demo1()
# demo2()
if __name__ == '__main__':
main()
2. 线程和进程之间的对比
进程:能够完成多任务,一台电脑上可以同时运行多个QQ
线程:能够完成多任务,一个QQ中的多个聊天窗口
根本区别:进程是操作系统资源分配的基本单位,线程是任务调度和执行的基本单位
3. 进程之间的通信
Queue-队列 先进先出
- 导入进程队列模块(注意与普通线程的队列的区分) from multiprocessing import Queue
- 使用方式与普通线程的队列方式类似
- put_nowait() ,使用后,当队列满了,会报错;若使用put(),队列满了,不会报错,会一直处于堵塞状态
# from queue import Queue # 普通线程的队列
from multiprocessing import Queue # 进程的队列
# q = Queue(3)
# 存数据
# q.put(1)
# q.put(2)
# q.put(3)
# # q.put(4) # 堵塞
# # q.put_nowait(4) # queue.Full 报错
#
# # 取值
# print(q.get())
# print(q.get())
# print(q.get())
# print(q.get()) # 堵塞
进程间的通信
def download(q):
lst = [11,22,33,44,55]
for i in lst:
q.put(i)
print('download finish')
def parse_data(q):
data = []
while True:
Data = q.get()
data.append(Data)
if q.empty():
break
print(data)
def main():
# q = Queue() 普通队列不可以
q = multiprocessing.Queue()
p1 = multiprocessing.Process(target=download,args=(q,))
p2 = multiprocessing.Process(target=parse_data,args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
print('ok')
if __name__ == '__main__':
main()
输出:
download finish
[11, 22, 33, 44, 55]
ok
共享全局变量不适用于多进程编程
import multiprocessing
a = 1
def demo1():
global a
a += 1
def demo2():
print(a)
if __name__ == '__main__':
t1 = multiprocessing.Process(target=demo1)
t2 = multiprocessing.Process(target=demo2)
t1.start()
t2.start()
输出结果:
1
4. 进程池之间的通信
当需要创建的⼦进程数量不多时,可以直接利用multiprocessing中的Process动态生成多个进程,但是如果是成百上千个目标,手动的去创建的进程的工作量巨大,此时就可以用multiprocessing模块提供的Pool方法
- 进程池的创建和使用:
from multiprocessing import Pool
import os, time, random
def worker(msg):
t_start = time.time()
print('%s开始执行,进程号为%d' % (msg, os.getpid()))
time.sleep(random.random() * 2)
t_stop = time.time()
print(msg, "执行完成,耗时%0.2f" % (t_stop - t_start))
def demo():
pass
if __name__ == '__main__':
po = Pool(5) # 定义一个进程池
for i in range(0, 10):
po.apply_async(worker, (i,))
print("--start--")
po.close()
#po.apply_async(demo) #无法加入至进程池,因为进程池已关闭
po.join()
print("--end--")
- 进程池之间的通信
import multiprocessing
def demo1(q):
print(1)
q.put('a')
def demo2(q):
print(2)
print(q.get())
if __name__ == '__main__':
# q = multiprocessing.Queue()
q = multiprocessing.Manager().Queue() # 进程池之间进程间的通信
po = multiprocessing.Pool(2)
po.apply_async(demo1,args=(q,))
po.apply_async(demo2,args=(q,))
po.close()
po.join()
输出:
1
2
a