python多进程和多线程究竟谁更快(详解)


Posted in Python onMay 29, 2017

python3.6

threading和multiprocessing

四核+三星250G-850-SSD

自从用多进程和多线程进行编程,一致没搞懂到底谁更快。网上很多都说python多进程更快,因为GIL(全局解释器锁)。但是我在写代码的时候,测试时间却是多线程更快,所以这到底是怎么回事?最近再做分词工作,原来的代码速度太慢,想提速,所以来探求一下有效方法(文末有代码和效果图)

这里先来一张程序的结果图,说明线程和进程谁更快

python多进程和多线程究竟谁更快(详解)

一些定义

并行是指两个或者多个事件在同一时刻发生。并发是指两个或多个事件在同一时间间隔内发生

线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一个程序的执行实例就是一个进程。

实现过程

而python里面的多线程显然得拿到GIL,执行code,最后释放GIL。所以由于GIL,多线程的时候拿不到,实际上,它是并发实现,即多个事件,在同一时间间隔内发生。

但进程有独立GIL,所以可以并行实现。因此,针对多核CPU,理论上采用多进程更能有效利用资源。

现实问题

在网上的教程里面,经常能见到python多线程的身影。比如网络爬虫的教程、端口扫描的教程。

这里拿端口扫描来说,大家可以用多进程实现下面的脚本,会发现python多进程更快。那么不就是和我们分析相悖了吗?

import sys,threading
from socket import *

host = "127.0.0.1" if len(sys.argv)==1 else sys.argv[1]
portList = [i for i in range(1,1000)]
scanList = []
lock = threading.Lock()
print('Please waiting... From ',host)


def scanPort(port):
  try:
    tcp = socket(AF_INET,SOCK_STREAM)
    tcp.connect((host,port))
  except:
    pass
  else:
    if lock.acquire():
      print('[+]port',port,'open')
      lock.release()
  finally:
    tcp.close()

for p in portList:
  t = threading.Thread(target=scanPort,args=(p,))
  scanList.append(t)
for i in range(len(portList)):
  scanList[i].start()
for i in range(len(portList)):
  scanList[i].join()

谁更快

因为python锁的问题,线程进行锁竞争、切换线程,会消耗资源。所以,大胆猜测一下:

在CPU密集型任务下,多进程更快,或者说效果更好;而IO密集型,多线程能有效提高效率。

大家看一下下面的代码:

import time
import threading
import multiprocessing

max_process = 4
max_thread = max_process

def fun(n,n2):
  #cpu密集型
  for i in range(0,n):
    for j in range(0,(int)(n*n*n*n2)):
      t = i*j

def thread_main(n2):
  thread_list = []
  for i in range(0,max_thread):
    t = threading.Thread(target=fun,args=(50,n2))
    thread_list.append(t)

  start = time.time()
  print(' [+] much thread start')
  for i in thread_list:
    i.start()
  for i in thread_list:
    i.join()
  print(' [-] much thread use ',time.time()-start,'s')

def process_main(n2):
  p = multiprocessing.Pool(max_process)
  for i in range(0,max_process):
    p.apply_async(func = fun,args=(50,n2))
  start = time.time()
  print(' [+] much process start')
  p.close()#关闭进程池
  p.join()#等待所有子进程完毕
  print(' [-] much process use ',time.time()-start,'s')

if __name__=='__main__':
  print("[++]When n=50,n2=0.1:")
  thread_main(0.1)
  process_main(0.1)
  print("[++]When n=50,n2=1:")
  thread_main(1)
  process_main(1)
  print("[++]When n=50,n2=10:")
  thread_main(10)
  process_main(10)

结果如下:

python多进程和多线程究竟谁更快(详解)

可以看出来,当对cpu使用率越来越高的时候(代码循环越多的时候),差距越来越大。验证我们猜想

CPU和IO密集型

1、CPU密集型代码(各种循环处理、计数等等)

2、IO密集型代码(文件处理、网络爬虫等)

判断方法:

1、直接看CPU占用率, 硬盘IO读写速度

2、计算较多->CPU;时间等待较多(如网络爬虫)->IO

3、请自行百度

以上这篇python多进程和多线程究竟谁更快(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python标准库os.path包、glob包使用实例
Nov 25 Python
python相似模块用例
Mar 04 Python
Python enumerate索引迭代代码解析
Jan 19 Python
pyhanlp安装介绍和简单应用
Feb 22 Python
Python神奇的内置函数locals的实例讲解
Feb 22 Python
在python里面运用多继承方法详解
Jul 01 Python
python IDLE 背景以及字体大小的修改方法
Jul 12 Python
python fuzzywuzzy模块模糊字符串匹配详细用法
Aug 29 Python
pytorch如何冻结某层参数的实现
Jan 10 Python
python实现翻译word表格小程序
Feb 27 Python
Python urllib.request对象案例解析
May 11 Python
opencv+python实现鼠标点击图像,输出该点的RGB和HSV值
Jun 02 Python
python 3利用BeautifulSoup抓取div标签的方法示例
May 28 #Python
Python虚拟环境virtualenv的安装与使用详解
May 28 #Python
python 调用win32pai 操作cmd的方法
May 28 #Python
Python 稀疏矩阵-sparse 存储和转换
May 27 #Python
Django基础之Model操作步骤(介绍)
May 27 #Python
python之PyMongo使用总结
May 26 #Python
Python3安装Pymongo详细步骤
May 26 #Python
You might like
分享一则PHP定义函数代码
2015/02/26 PHP
php微信公众平台配置接口开发程序
2016/09/22 PHP
PHP操作Redis常用技巧总结
2018/04/24 PHP
在laravel框架中实现封装公共方法全局调用
2019/10/14 PHP
jquery 插件学习(六)
2012/08/06 Javascript
用js调用迅雷下载代码的二种方法
2013/04/15 Javascript
简单几行JS Code实现IE邮件转发新浪微博
2013/07/03 Javascript
jQuery实现图片文字淡入淡出效果
2015/12/21 Javascript
JS冒泡事件与事件捕获实例详解
2016/11/25 Javascript
使用ES6语法重构React代码详解
2017/05/09 Javascript
Vue中父子组件通讯之todolist组件功能开发
2018/05/21 Javascript
使用react render props实现倒计时的示例代码
2018/12/06 Javascript
ES6之Proxy的get方法详解
2019/10/11 Javascript
js实现简单贪吃蛇游戏
2020/05/15 Javascript
ng-alain的sf如何自定义部件的流程
2020/06/12 Javascript
工作中常用js功能汇总
2020/11/07 Javascript
vue实现按钮切换图片
2021/01/20 Vue.js
[02:08]2014DOTA2国际邀请赛 430专访:力争取得小组前二
2014/07/11 DOTA
Python方法的延迟加载的示例代码
2017/12/18 Python
python 自动批量打开网页的示例
2019/02/21 Python
Python爬虫requests库多种用法实例
2020/05/28 Python
python数据抓取3种方法总结
2021/02/07 Python
Django和Ueditor自定义存储上传文件的文件名
2021/02/25 Python
css3 2D图片转动样式可以扩充到Js当中
2014/04/29 HTML / CSS
阳光体育:Sunny Sports(购买露营和远足设备)
2018/08/07 全球购物
Mountain Warehouse德国官网:英国户外零售商
2019/08/11 全球购物
介绍一下MD5加密算法
2016/11/12 面试题
药剂专业学生求职信范文
2013/12/28 职场文书
大学生党课思想汇报
2013/12/29 职场文书
给水工程专业毕业生自荐信
2014/01/28 职场文书
环境科学专业优秀毕业生自荐书
2014/02/03 职场文书
授权委托书怎么写
2014/09/25 职场文书
群众路线专项整治方案
2014/10/27 职场文书
业务员辞职信范文
2015/03/02 职场文书
2015年度团总支工作总结
2015/04/23 职场文书
写给媳妇的检讨书
2015/05/06 职场文书