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 元组(Tuple)操作详解
Mar 11 Python
详解Python list 与 NumPy.ndarry 切片之间的对比
Jul 24 Python
基于Django URL传参 FORM表单传数据 get post的用法实例
May 28 Python
python使用epoll实现服务端的方法
Oct 16 Python
Python+OpenCV图片局部区域像素值处理详解
Jan 23 Python
Python实现的读取文件内容并写入其他文件操作示例
Apr 09 Python
通过python实现随机交换礼物程序详解
Jul 10 Python
Django 在iframe里跳转顶层url的例子
Aug 21 Python
Python交互环境下打印和输入函数的实例内容
Feb 16 Python
Django 自定义404 500等错误页面的实现
Mar 08 Python
Pytorch数据拼接与拆分操作实现图解
Apr 30 Python
如何写python的配置文件
Jun 07 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中对用户身份认证实现两种方法
2011/06/04 PHP
php简单生成随机数的方法
2015/07/30 PHP
PHP利用curl发送HTTP请求的实例代码
2020/07/09 PHP
PHP执行普通shell命令流程解析
2020/08/24 PHP
Nigma vs Alliance BO5 第五场2.14
2021/03/10 DOTA
用js实现的检测浏览器和系统的函数
2009/04/09 Javascript
关于javascript function对象那些迷惑分析
2011/10/24 Javascript
js判断鼠标同时离开两个div的思路及代码
2013/05/31 Javascript
jquery 实现密码框的显示与隐藏示例代码
2013/09/18 Javascript
JavaScript中遍历对象的property的3种方法介绍
2014/12/30 Javascript
JavaScript实现俄罗斯方块游戏过程分析及源码分享
2015/03/23 Javascript
关于微信中a链接无法跳转问题
2016/08/02 Javascript
js带闹铃功能的倒计时代码
2016/09/29 Javascript
VUE v-for循环中每个item节点动态绑定不同函数的实例
2018/09/26 Javascript
详解Webstorm 下的Angular2.0开发之路(图文)
2018/12/06 Javascript
每周一练 之 数据结构与算法(Stack)
2019/04/16 Javascript
微信小程序环境下将文件上传到OSS的方法步骤
2019/05/31 Javascript
webpack自动打包和热更新的实现方法
2019/06/24 Javascript
Javascript Dom元素获取和添加详解
2019/09/24 Javascript
JavaScript 面向对象基础简单示例
2019/10/02 Javascript
使用eslint和githooks统一前端风格的技巧
2020/07/29 Javascript
[02:46]解说DC:感谢430陪伴我们的DOTA2国际邀请赛岁月
2016/06/29 DOTA
python中循环语句while用法实例
2015/05/16 Python
Python ftp上传文件
2016/02/13 Python
python flask 多对多表查询功能
2017/06/25 Python
Python双精度浮点数运算并分行显示操作示例
2017/07/21 Python
python中字符串变二维数组的实例讲解
2018/04/03 Python
Python读取pdf表格写入excel的方法
2021/01/22 Python
使用HTML5进行SVG矢量图形绘制的入门教程
2016/02/19 HTML / CSS
Debenhams百货英国官方网站:Debenhams UK
2016/07/12 全球购物
Jo Malone美国官网:祖玛珑香水
2017/03/27 全球购物
五星级酒店餐饮部总监的标准岗位职责
2014/02/17 职场文书
工地宣传标语
2014/06/18 职场文书
党委班子剖析材料
2014/08/21 职场文书
群众路线个人对照检查材料
2014/09/23 职场文书
Java图书管理系统,课程设计必用(源码+文档)
2021/06/30 Java/Android