python多任务4-2
多进程
- 1什么是进程?
进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
说白了就是你的代码运行起来了就是一个进程。具有独立的资源单位,写的程序跑起来的实体就是进程
- 2 什么是多进程
多进程就是你的程序,通俗的理解没运行起来就是程序,运行起来了就是一个进程程序只有一个,进程可以有多个,就好比我们的qq应用可以再电脑上登录好几个qq应用。进程就是拥有资源的,程序没运行起来不会使用资源的只是一些代码,一些二进制而已。当我们运行多个应用的时候这个就是多进程。
进程的状态:
代码实现
导入我们需要的包,multiprocessing
import multiprocessing
import time
def sum1(num1):
for i in range(num1):
print("this is num1111 = %d", i)
time.sleep(1)
def sum2(num2):
for i in range(num2):
print("this is num2222 = %d", i)
time.sleep(1)
def main():
# 创建一个进程,这个和创建线程基本上是一样的。
pro1 = multiprocessing.Process(target=sum1,args=(10,))
pro2 = multiprocessing.Process(target=sum2,args=(10,))
pro1.start()
pro2.start()
if __name__ == "__main__":
main()
运行的结果:我们通过任务管理器可以看到有三个进程
一个是主进程,另外两个是子进程。
进程间的通信
方式一:通过socket
方式二:用队列
方式三:通过公用一个文件(这个因为要进行读取文件所以会慢很多)
套接字我们前面在tcp和udp讲过了,所以这里就不说了
我们直接讲用的比较多的就是队列
什么是队列,队列的一大特点就是先进先出与之对应的就是栈先进后出。
我们知道火车进山洞火车头先进去那么先出来的也是火车头。
这里我们通过队列实现各个进程之间的数据交流
代码实现
# 初始化一个队列的对象 3表示可以存放的put几个可以接受3条put消息
que = multiprocessing.Queue(3)
# 放数据
que.put("数据1")
# 取数据
que.get()
# 判断是否满了 满了返回True
que.full()
# 判断是否空的 空的返回True
que.empty()
===========================================================
完整代码
==========================================================
import multiprocessing
import time
def send_data(num1, que):
datas = ["你", "好", "收", "到", "回", "复"]
for data in datas:
print("开始发送数据",data)
que.put(data)
print("是否满了:",que.full())
def receive_data(num2, que):
data_list = list()
while True:
time.sleep(0.1)
if que.empty():
print("退出了")
break
data_list.append(que.get())
print(data_list)
def main():
# 初始化一个队列的对象 3表示可以存放的put几个可以接受3条put消息
que = multiprocessing.Queue(1)
pro1 = multiprocessing.Process(target=send_data,args=[10, que])
pro2 = multiprocessing.Process(target=receive_data,args=[10, que])
pro1.start()
pro2.start()
if __name__ == "__main__":
main()
运行结果
进程池
我们通过以上可知当我们的程序越来越复杂,这个时候进程越多反而不利于系统的效率,只有达到一个平衡点才是最优的。进程池就是里面都是进程可能10个也可能5个或者3个就这些根据需要创建,当我需要的时候就调用就行了,不需要的时候就不用调用。
举个例子:划船馆中总共有10条船,当来5个客人的时候,我就拿出5条船给与他们,当来100个人的时候,给10个人一人一条去划船,其他90人等待,当10个人中谁用好了再给90人中的其他人,就是重复利用。
初始化Pool(进程池)时,可以指定一个最大进程数,当有新的请求提交到Pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到指定的最大值,那么该请求就会等待,直到池中有进程结束,才会用之前的进程来执行新的任务,请看下面的实例:
from multiprocessing import Pool
import os, time
def worker(i):
time.sleep(1)
print("进程号为:",os.getpid(),i)
def main():
# 定义一个进程池最大进程数为3,并不会马上创建而是调用的时候再创建
po = Pool(3)
print("start -----")
for i in range(10):
# 对于apply和apply_async
# apply 表示阻塞,当有三个子进程的是时候,
# 他们是顺序执行,当执行完第一个再执行第二个接着第三个
po.apply_async(worker,(i,))
关闭进程池,其中注意close必须再join前面
po.close()
# 等待所有的进程进行完后再结束主进程,因为线程会等子线程运行完再关,而进程不会等
# 所以要加上join()
po.join()
print("end-----------")
if __name__ == "__main__":
main()
运行结果可以看到只有三个进程再交替运行。
对于apply和apply_async,apply 表示阻塞,当有三个子进程的是时候,他们是顺序执行,当执行完第一个再执行第二个接着第三个,apply_async表示异步就是三个进程一起运行
接着向下看,有彩蛋……
在进程池中用队列
import multiprocessing import Manager,Pool
qu = Manager().Queue()
qu.put(数据1)
qu.get()得到一个数据
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/119320.html