Python多进程与多线程的使用场景详解

前言

Python多进程适用的场景:计算密集型(CPU密集型)任务

Python多线程适用的场景:IO密集型任务

计算密集型任务一般指需要做大量的逻辑运算,比如上亿次的加减乘除,使用多核CPU可以并发提高计算性能。

IO密集型任务一般指输入输出型,比如文件的读取,或者网络的请求,这类场景一般会遇到IO阻塞,使用多核CPU来执行并不会有太高的性能提升。

下面使用一台64核的虚拟机来执行任务,通过示例代码来区别它们,

示例1:执行计算密集型任务,进行1亿次运算

使用多进程

from multiprocessing import Process
import os, time

# 计算密集型任务
def work():
 res = 0
 for i in range(100 * 100 * 100 * 100): # 亿次运算
  res *= i

if __name__ == "__main__":
 l = []
 print("本机为", os.cpu_count(), "核 CPU") # 本机为64核
 start = time.time()
 for i in range(4):
  p = Process(target=work) # 多进程
  l.append(p)
  p.start()
 for p in l:
  p.join()
 stop = time.time()
 print("计算密集型任务,多进程耗时 %s" % (stop - start))

使用多线程

from threading import Thread
import os, time

# 计算密集型任务
def work():
 res = 0
 for i in range(100 * 100 * 100 * 100): # 亿次运算
  res *= i

if __name__ == "__main__":
 l = []
 print("本机为", os.cpu_count(), "核 CPU") # 本机为64核
 start = time.time()
 for i in range(4):
  p = Thread(target=work) # 多线程
  l.append(p)
  p.start()
 for p in l:
  p.join()
 stop = time.time()
 print("计算密集型任务,多线程耗时 %s" % (stop - start))

两段代码输出:

本机为 64 核 CPU
计算密集型任务,多进程耗时 6.864224672317505
 
本机为 64 核 CPU
计算密集型任务,多线程耗时 37.91042113304138

说明:上述代码中,分别使用4个多进程和4个多线程去执行亿次运算,多进程耗时6.86s,多线程耗时37.91s,可见在计算密集型任务场景,使用多进程能大大提高效率。

另外,当分别使用8个多进程和8个多线程去执行亿次运算时,耗时差距更大,输出如下:

本机为 64 核 CPU
计算密集型任务,多进程耗时 6.811635971069336
 
本机为 64 核 CPU
计算密集型任务,多线程耗时 113.53767895698547

可见在64核的cpu机器下,同时使用8个多进程和4个多进程效率几乎一样。而使用多线程则就效率较慢。要最高效地利用CPU,计算密集型任务同时进行的数量应当等于CPU的核心数

示例2:400次,阻塞两秒,读取文件

使用多进程(4核cpu)

from multiprocessing import Process
import os, time

# I/0密集型任务
def work():
 time.sleep(5) # 阻塞两秒

if __name__ == "__main__":
 l = []
 print("本机为", os.cpu_count(), "核 CPU")
 start = time.time()
 for i in range(1000):
  p = Process(target=work) # 多进程
  l.append(p)
  p.start()
 for p in l:
  p.join()
 stop = time.time()
 print("I/0密集型任务,多进程耗时 %s" % (stop - start))

使用多线程(4核cpu)

from threading import Thread
import os, time

# I/0密集型任务
def work():
 time.sleep(5) # 阻塞两秒

if __name__ == "__main__":
 l = []
 print("本机为", os.cpu_count(), "核 CPU")
 start = time.time()

 for i in range(1000):
  p = Thread(target=work) # 多线程
  l.append(p)
  p.start()
 for p in l:
  p.join()
 stop = time.time()
 print("I/0密集型任务,多线程耗时 %s" % (stop - start))

输出:

本机为 64 核 CPU
I/0密集型任务,多进程耗时 12.28218412399292
 
 
本机为 64 核 CPU
I/0密集型任务,多线程耗时 5.399136066436768

说明:python的多线程有于GIL锁的存在,无论是多少核的cpu机器,也只能使用单核,从输出结果来看,对于IO密集型任务使用多线程比较占优。

FAQ:执行多进程的io密集型任务时,报了一个错:

OSError: [Errno 24] Too many open files

原因:linux系统限制

ulimit -n
# 输出 1024

解决:(临时提高系统限制,重启后失效)

ulimit -n 10240

总结

到此这篇关于Python多进程与多线程使用场景的文章就介绍到这了,更多相关Python多进程与使用场景内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python多进程并发(multiprocessing)用法实例详解

    本文实例讲述了Python多进程并发(multiprocessing)用法.分享给大家供大家参考.具体分析如下: 由于Python设计的限制(我说的是咱们常用的CPython).最多只能用满1个CPU核心. Python提供了非常好用的多进程包multiprocessing,你只需要定义一个函数,Python会替你完成其他所有事情.借助这个包,可以轻松完成从单进程到并发执行的转换. 1.新建单一进程 如果我们新建少量进程,可以如下: import multiprocessing import t

  • Python多进程库multiprocessing中进程池Pool类的使用详解

    问题起因 最近要将一个文本分割成好几个topic,每个topic设计一个regressor,各regressor是相互独立的,最后汇总所有topic的regressor得到总得预测结果.没错!类似bagging ensemble!只是我没有抽样.文本不大,大概3000行,topic个数为8,于是我写了一个串行的程序,一个topic算完之后再算另一个topic.可是我在每个topic中用了GridSearchCV来调参,又要选特征又要调整regressor的参数,导致参数组合一共有1782种.我真

  • Python多进程通信Queue、Pipe、Value、Array实例

    queue和pipe的区别: pipe用来在两个进程间通信.queue用来在多个进程间实现通信. 此两种方法为所有系统多进程通信的基本方法,几乎所有的语言都支持此两种方法. 1)Queue & JoinableQueue queue用来在进程间传递消息,任何可以pickle-able的对象都可以在加入到queue. multiprocessing.JoinableQueue 是 Queue的子类,增加了task_done()和join()方法. task_done()用来告诉queue一个tas

  • Python多进程分块读取超大文件的方法

    本文实例讲述了Python多进程分块读取超大文件的方法.分享给大家供大家参考,具体如下: 读取超大的文本文件,使用多进程分块读取,将每一块单独输出成文件 # -*- coding: GBK -*- import urlparse import datetime import os from multiprocessing import Process,Queue,Array,RLock """ 多进程分块读取文件 """ WORKERS = 4

  • Python多进程multiprocessing.Pool类详解

    multiprocessing模块 multiprocessing包是Python中的多进程管理包.它与 threading.Thread类似,可以利用multiprocessing.Process对象来创建一个进程.该进程可以允许放在Python程序内部编写的函数中.该Process对象与Thread对象的用法相同,拥有is_alive().join([timeout]).run().start().terminate()等方法.属性有:authkey.daemon(要通过start()设置)

  • 浅析Python中的多进程与多线程的使用

    在批评Python的讨论中,常常说起Python多线程是多么的难用.还有人对 global interpreter lock(也被亲切的称为"GIL")指指点点,说它阻碍了Python的多线程程序同时运行.因此,如果你是从其他语言(比如C++或Java)转过来的话,Python线程模块并不会像你想象的那样去运行.必须要说明的是,我们还是可以用Python写出能并发或并行的代码,并且能带来性能的显著提升,只要你能顾及到一些事情.如果你还没看过的话,我建议你看看Eqbal Quran的文章

  • Python中使用多进程来实现并行处理的方法小结

    进程和线程是计算机软件领域里很重要的概念,进程和线程有区别,也有着密切的联系,先来辨析一下这两个概念: 1.定义 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源. 2.关系 一个线程可以创建和撤

  • Python控制多进程与多线程并发数总结

    一.前言 本来写了脚本用于暴力破解密码,可是1秒钟尝试一个密码2220000个密码我的天,想用多线程可是只会一个for全开,难道开2220000个线程吗?只好学习控制线程数了,官方文档不好看,觉得结构不够清晰,网上找很多文章也都不很清晰,只有for全开线程,没有控制线程数的具体说明,最终终于根据多篇文章和官方文档算是搞明白基础的多线程怎么实现法了,怕长时间不用又忘记,找着麻烦就贴这了,跟我一样新手也可以参照参照. 先说进程和线程的区别: 地址空间:进程内的一个执行单元;进程至少有一个线程;它们共

  • 探究Python多进程编程下线程之间变量的共享问题

     1.问题: 群中有同学贴了如下一段代码,问为何 list 最后打印的是空值? from multiprocessing import Process, Manager import os manager = Manager() vip_list = [] #vip_list = manager.list() def testFunc(cc): vip_list.append(cc) print 'process id:', os.getpid() if __name__ == '__main_

  • Python多进程同步Lock、Semaphore、Event实例

    同步的方法基本与多线程相同. 1) Lock 当多个进程需要访问共享资源的时候,Lock可以用来避免访问的冲突. 复制代码 代码如下: import multiprocessing import sys def worker_with(lock, f):     with lock:         fs = open(f,"a+")         fs.write('Lock acquired via with\n')         fs.close()         def

随机推荐