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基于scrapy采集数据时使用代理服务器的方法
Apr 16 Python
Python多线程和队列操作实例
Jun 21 Python
python读取和保存视频文件
Apr 16 Python
selenium+python设置爬虫代理IP的方法
Nov 29 Python
Python使用字典的嵌套功能详解
Feb 27 Python
在linux下实现 python 监控usb设备信号
Jul 03 Python
在Pycharm中调试Django项目程序的操作方法
Jul 17 Python
Python Pickle 实现在同一个文件中序列化多个对象
Dec 30 Python
django实现模型字段动态choice的操作
Apr 01 Python
浅谈python opencv对图像颜色通道进行加减操作溢出
Jun 03 Python
如何使用python socket模块实现简单的文件下载
Sep 04 Python
Python 装饰器(decorator)常用的创建方式及解析
Apr 24 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实现手机归属地查询API接口实现代码
2012/08/27 PHP
jquery入门—选择器实现隔行变色实例代码
2013/01/04 Javascript
5秒后跳转效果(setInterval/SetTimeOut)
2013/05/03 Javascript
SeaJS 与 RequireJS 的差异对比
2014/12/08 Javascript
jQuery简单实现遍历数组的方法
2015/04/14 Javascript
JavaScript改变CSS样式的方法汇总
2015/05/07 Javascript
JavaScript中的this,call,apply使用及区别详解
2016/01/29 Javascript
使用NodeJs 开发微信公众号(三)微信事件交互实例
2016/03/02 NodeJs
jstl中判断list中是否包含某个值的简单方法
2016/10/14 Javascript
Javascript实现数组中的元素上下移动
2017/04/28 Javascript
BootStrap Table前台和后台分页对JSON格式的要求
2017/06/28 Javascript
vue组件初学_弹射小球(实例讲解)
2017/09/06 Javascript
Vue 2.0入门基础知识之内部指令详解
2017/10/15 Javascript
vue使用keep-alive实现数据缓存不刷新
2017/10/21 Javascript
Vue动态创建注册component的实例代码
2019/06/14 Javascript
纯js实现无缝滚动功能代码实例
2020/02/21 Javascript
vue+iview使用树形控件的具体使用
2020/11/02 Javascript
vue项目打包后请求地址错误/打包后跨域操作
2020/11/04 Javascript
Python获取当前路径实现代码
2017/05/08 Python
利用Python批量压缩png方法实例(支持过滤个别文件与文件夹)
2017/07/30 Python
Python网络编程使用select实现socket全双工异步通信功能示例
2018/04/09 Python
Python之批量创建文件的实例讲解
2018/05/10 Python
python3中os.path模块下常用的用法总结【推荐】
2018/09/16 Python
Python实现平行坐标图的两种方法小结
2019/07/04 Python
Python GUI库PyQt5样式QSS子控件介绍
2020/02/25 Python
Python tkinter制作单机五子棋游戏
2020/09/14 Python
在Python中实现字典反转案例
2020/12/05 Python
世界上最受欢迎的花店:1-800-Flowers.com
2020/06/01 全球购物
统计每一学生的平均成绩
2014/06/06 面试题
Laravel中Kafka的使用详解
2021/03/24 PHP
大专生简历的自我评价
2013/11/26 职场文书
音乐节策划方案
2014/06/09 职场文书
计算机科学与技术专业求职信
2014/09/03 职场文书
解除劳动合同协议书
2014/09/17 职场文书
大班上学期个人总结
2015/02/13 职场文书
MongoDB使用profile分析慢查询的步骤
2021/04/30 MongoDB