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时间模块datetime、time、calendar的使用方法
Jan 13 Python
Python用sndhdr模块识别音频格式详解
Jan 11 Python
解决python 未发现数据源名称并且未指定默认驱动程序的问题
Dec 07 Python
Python 隐藏输入密码时屏幕回显的实例
Feb 19 Python
Python实现语音识别和语音合成功能
Sep 20 Python
python实现银行管理系统
Oct 25 Python
浅谈python print(xx, flush = True) 全网最清晰的解释
Feb 21 Python
Python使用ElementTree美化XML格式的操作
Mar 06 Python
用 Python 制作地球仪的方法
Apr 24 Python
浅谈Python中的生成器和迭代器
Jun 19 Python
用python自动生成日历
Apr 24 Python
Python实现将多张图片合成MP4视频并加入背景音乐
Apr 28 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中使用TCPDF生成PDF文档实例
2014/07/01 PHP
学习php设计模式 php实现观察者模式(Observer)
2015/12/09 PHP
php 浮点数比较方法详解
2017/05/05 PHP
Thinkphp 空操作、空控制器、命名空间(详解)
2017/05/05 PHP
laravel框架模型、视图与控制器简单操作示例
2019/10/10 PHP
仅IE9/10同时支持script元素的onload和onreadystatechange事件分析
2011/04/27 Javascript
JavaScript中“+”的陷阱深刻理解
2012/12/04 Javascript
javascript中拼接HTML字符串的最快、最好的方法
2014/06/07 Javascript
angularjs 处理多个异步请求方法汇总
2015/01/06 Javascript
简单的jQuery入门指引
2015/07/28 Javascript
表单元素值获取方式js及java方式的简单实例
2016/10/15 Javascript
你不知道的 javascript【推荐】
2017/01/08 Javascript
原生js实现对Ajax的封装(仿jquery)
2017/01/22 Javascript
Bootstrap 3 进度条的实现
2017/02/22 Javascript
webpack中CommonsChunkPlugin详细教程(小结)
2017/11/09 Javascript
JS中的回调函数实例浅析
2018/03/21 Javascript
对layui中表单元素的使用详解
2018/08/15 Javascript
js删除对象中的某一个字段的方法实现
2021/01/11 Javascript
原生js实现自定义难度的扫雷游戏
2021/01/22 Javascript
一文秒懂nodejs中的异步编程
2021/01/28 NodeJs
Django中更新多个对象数据与删除对象的方法
2015/07/17 Python
python画图系列之个性化显示x轴区段文字的实例
2018/12/13 Python
python检测IP地址变化并触发事件
2018/12/26 Python
Python线程池模块ThreadPoolExecutor用法分析
2018/12/28 Python
Python饼状图的绘制实例
2019/01/15 Python
Python3.4学习笔记之常用操作符,条件分支和循环用法示例
2019/03/01 Python
python scatter散点图用循环分类法加图例
2019/03/19 Python
python实现爬取百度图片的方法示例
2019/07/06 Python
Python input函数使用实例解析
2019/11/22 Python
Html5 Canvas动画基础碰撞检测的实现
2018/12/06 HTML / CSS
Microsoft新加坡官方网站:购买微软最新软件和技术产品
2016/10/28 全球购物
DC Shoes澳大利亚官方网上商店:购买DC鞋子
2019/10/25 全球购物
计算机专业求职信
2014/06/02 职场文书
2014年药房工作总结
2014/11/22 职场文书
2015年个人实习工作总结
2014/12/12 职场文书
广告业务员岗位职责
2015/02/13 职场文书