目录
进程的创建模块 - multiprocessing创建进程函数 - Process进程的常用方法start 函数join 函数kill 函数 与 is_alive 函数进程的相关问题该章节我们来学习一下在 Python 中去创建并使用多进程的方法,通过学习该章节,我们将可以通过创建多个进程来帮助我们提高脚本执行的效率。可以认为缩短脚本执行的时间,就是提高执行我们脚本的效率。接下来让我们都看一下今天的章节知识点都有哪些?
进程的创建模块 - multiprocessing
创建进程函数 - Process
函数名 | 介绍 | 参数 | 返回值 |
---|---|---|---|
Process | 创建一个进程 | target, args | 进程对象 |
Process功能介绍:实例化一个对象;它需要传入两个参数 target 与 args:target 是一个函数,args 是对应一个函数的参数(args参数是一个元组)。其实我们可以这样去理解,在一个脚本中创建子进程,目的是为了让它执行我们脚本中的某个函数。换句话讲,我们将脚本中的某一个函数单独的启用一个进程去执行。
我们说过进程之间互不干扰,可以同时执行。所以我们可以认为主进程中的程序和子进程的函数是相互不干扰的,听起来可能很难理解,一会儿下文我们进行一个案例的小练习,一遍帮助大家去更好的理解其中的含义。
进程的常用方法
函数名 | 介绍 | 参数 | 返回值 |
---|---|---|---|
start | 执行进程 | 无 | 无 |
join | 阻塞进程 | 无 | 无 |
kill | 杀死进程 | 无 | 无 |
is_alive | 判断进程是否存活 | 无 | bool |
start 函数
演示案例:
我们先定义两个简单的函数,每个函数定义两个简单的 for 循环。每执行一次循环,休眠一秒的时间。在两次循环的开始定义一个实例化时间对象,用以计算两次循环的时间间隔。同时,获取脚本执行的进程号; 看看是一个怎样的结果。# coding:utf-8 import time import os def work_for_first(): for i in range(5): print("\"work_for_first\" 函数的循环值:%s", "进程号为:%s" % i, os.getpid()) # os.getpid() 为获取进程号函数 time.sleep(1) def work_for_second(): for i in range(5): print("\"work_for_second\" 函数的循环值:%s", "进程号为:%s" % i, os.getpid()) time.sleep(1) if __name__ == "__main__": start_time = time.time() # 获取执行 循环 之前的时间戳 work_for_first() work_for_second() end_time = time.time() - start_time # 获取执行 循环 结束的时间戳 print("耗时时间为:{}, 进程号为:{}".format(end_time, os.getpid())) # 获取耗时与进程号
执行结果如下图:
OKK!接下来进入我们今天要学习的主题。
将 work_for_first() 函数创建一个新的子进程去执行。
# coding:utf-8 import time import os import multiprocessing def work_for_first(): for i in range(5): print("\"work_for_first\" 函数的循环值:{},进程号为:{}".format(i, os.getpid())) time.sleep(1) def work_for_second(): for i in range(5): print("\"work_for_second\" 函数的循环值:{},进程号为:{}".format(i, os.getpid())) time.sleep(1) if __name__ == "__main__": start_time = time.time() # 获取执行 循环 之前的时间戳 work_for_first_process = multiprocessing.Process(target=work_for_first) # 因为我们传入的函数没有参数所以 args 可以不写 work_for_first_process.start() work_for_second() end_time = time.time() - start_time # 获取执行 循环 结束的时间戳 print("耗时时间为:{}, 进程号为:{}".format(end_time, os.getpid())) # 获取耗时与进程号
执行结果如下图:
因为我们针对 work_for_first() 函数创建一个新的子进程去执行,所以我们的耗时变为了 5秒。那么如果我们将 work_for_second() 函数也创建一个新的子进程去执行,耗时又会是多少呢?我们接着往下看。
# coding:utf-8 import time import os import multiprocessing def work_for_first(): for i in range(5): print("\"work_for_first\" 函数的循环值:{},进程号为:{}".format(i, os.getpid())) time.sleep(1) def work_for_second(): for i in range(5): print("\"work_for_second\" 函数的循环值:{},进程号为:{}".format(i, os.getpid())) time.sleep(1) if __name__ == "__main__": start_time = time.time() # 获取执行 循环 之前的时间戳 work_for_first_process = multiprocessing.Process(target=work_for_first) # 因为我们传入的函数没有参数所以 args 可以不写 work_for_first_process.start() work_for_second_process = multiprocessing.Process(target=work_for_second) work_for_second_process.start() end_time = time.time() - start_time # 获取执行 循环 结束的时间戳 print("耗时时间为:{}, 进程号为:{}".format(end_time, os.getpid())) # 获取耗时与进程号
执行结果如下图:
PS:从脚本中执行入口的 main 函数可以看出 work_for_first() 函数 与 work_for_second() 函数 分别都由各自的子进程来执行,主进程实际执行的 只有 23行、29行、30行代码,所以从耗时来看,主进程实际上只执行了 0.026 秒。
这里再思考一个问题,如果是每一个子进程都单独的通过 .start 去启动,那么在子进程很多的情况下,启动的确实会有一些慢了。这个时候我们就可以通过 for 循环的方式去启动子进程。方式如下:
for sun_process in (work_for_first_process, work_for_second_process): sun_process.start()
join 函数
同样的也会存在着这样一种情况,我们希望子进程运行结束之后再去执行我们的主进程,这时候我们就会使用到 join 函数 。
这里我们就利用上文的 进程 for循环同时启动两个子进程,然后我们再在下一个 for循环 执行 join 函数,我们看看会发生什么。
# coding:utf-8 import time import os import multiprocessing def work_for_first(): for i in range(5): print("\"work_for_first\" 函数的循环值:{},进程号为:{}".format(i, os.getpid())) time.sleep(1) def work_for_second(): for i in range(5): print("\"work_for_second\" 函数的循环值:{},进程号为:{}".format(i, os.getpid())) time.sleep(1) if __name__ == "__main__": start_time = time.time() # 获取执行 循环 之前的时间戳 work_for_first_process = multiprocessing.Process(target=work_for_first) # 因为我们传入的函数没有参数所以 args 可以不写 # work_for_first_process.start() work_for_second_process = multiprocessing.Process(target=work_for_second) # work_for_second_process.start() for sun_process in (work_for_first_process, work_for_second_process): sun_process.start() for sun_process in (work_for_first_process, work_for_second_process): sun_process.join() end_time = time.time() - start_time # 获取执行 循环 结束的时间戳 print("耗时时间为:{}, 进程号为:{}".format(end_time, os.getpid())) # 获取耗时与进程号
执行结果如下图:
kill 函数 与 is_alive 函数
接下来我们再尝试一个场景,利用 for 循环,我们同时启动 work_for_first() 函数 与 work_for_second() 函数 的子进程。然后我们再在另一个 for 循环中,将 work_for_second() 函数 的子进程 kill 掉,然后判断两个子进程的存活状态。
示例脚本如下:
# coding:utf-8 import time import os import multiprocessing def work_for_first(): for i in range(5): print("\"work_for_first\" 函数的循环值:{},进程号为:{}".format(i, os.getpid())) time.sleep(1) def work_for_second(): for i in range(5): print("\"work_for_second\" 函数的循环值:{},进程号为:{}".format(i, os.getpid())) time.sleep(1) if __name__ == "__main__": start_time = time.time() # 获取执行 循环 之前的时间戳 work_for_first_process = multiprocessing.Process(target=work_for_first) # 因为我们传入的函数没有参数所以 args 可以不写 # work_for_first_process.start() work_for_second_process = multiprocessing.Process(target=work_for_second) # work_for_second_process.start() for sun_process in (work_for_first_process, work_for_second_process): sun_process.start() time.sleep(1) # 休眠一秒是为了 work_for_second_process 子进程 至少能够运行一次 for sun_process in (work_for_first_process, work_for_second_process): work_for_second_process.kill() if work_for_first_process.is_alive(): print("\"work_for_first_process\" 子进程当前存活状态为:True") elif not work_for_second_process.is_alive(): print("\"work_for_second_process\" 子进程当前存活状态为:False") sun_process.join() end_time = time.time() - start_time # 获取执行 循环 结束的时间戳 print("耗时时间为:{}, 进程号为:{}".format(end_time, os.getpid())) # 获取耗时与进程号
运行结果如下:
进程的相关问题
通过学习多进程的创建、启动,我们可以充分的体会到进程给我们带来的好处。它可以使我们的脚本程序执行时间进行缩短,从而提高工作效率。
然而多进程也有一些问题:
通过进程模块执行的函数无法获取返回值,即便这个函数拥有 return 关键字也无法获取到,这也是我们进程的弊端。多个进程同时修改文件可能会出现错误。进程数量太多可能会造成资源不足、甚至死机等情况。关于进程的这些问题,其实也并不是不能解决。在后续更新的 进程间的通信 、进程池与进程锁 的章节我们再进行详细的介绍。
到此这篇关于Python语法学习之进程的创建与常用方法详解的文章就介绍到这了,更多相关Python 进程创建内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
X 关闭
X 关闭
- 15G资费不大降!三大运营商谁提供的5G网速最快?中国信通院给出答案
- 2联想拯救者Y70发布最新预告:售价2970元起 迄今最便宜的骁龙8+旗舰
- 3亚马逊开始大规模推广掌纹支付技术 顾客可使用“挥手付”结账
- 4现代和起亚上半年出口20万辆新能源汽车同比增长30.6%
- 5如何让居民5分钟使用到各种设施?沙特“线性城市”来了
- 6AMD实现连续8个季度的增长 季度营收首次突破60亿美元利润更是翻倍
- 7转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 8充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 9好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 10名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?