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实现上传下载文件功能
Nov 19 Python
python 实现一个贴吧图片爬虫的示例
Oct 12 Python
PyQt5每天必学之关闭窗口
Apr 19 Python
Python读写/追加excel文件Demo分享
May 03 Python
python3监控CentOS磁盘空间脚本
Jun 21 Python
python实现雨滴下落到地面效果
Jun 21 Python
Python基础知识点 初识Python.md
May 14 Python
windows上安装python3教程以及环境变量配置详解
Jul 18 Python
python 绘制国旗的示例
Sep 27 Python
python3 通过 pybind11 使用Eigen加速代码的步骤详解
Dec 07 Python
python爬取代理ip的示例
Dec 18 Python
selenium3.0+python之环境搭建的方法步骤
Feb 01 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
地摊中国 - 珍藏老照片
2020/08/18 杂记
php+mysql实现无限级分类 | 树型显示分类关系
2006/11/19 PHP
PHP中通过ADO调用Access数据库的方法测试不通过
2006/12/31 PHP
php Undefined index和Undefined variable的解决方法
2008/03/27 PHP
php adodb介绍
2009/03/19 PHP
php实现文件编码批量转换
2014/03/10 PHP
PHP实现的折半查询算法示例
2017/10/09 PHP
TP5框架使用QueryList采集框架爬小说操作示例
2020/03/26 PHP
JavaScript DOM操作表格及样式
2015/04/13 Javascript
jquery实现选中单选按钮下拉伸缩效果
2015/08/06 Javascript
JavaScript操作选择对象的简单实例
2016/05/16 Javascript
基于JS如何实现类似QQ好友头像hover时显示资料卡的效果(推荐)
2016/06/09 Javascript
Bootstrap弹出框(modal)垂直居中的问题及解决方案详解
2016/06/12 Javascript
分类解析jQuery选择器
2016/11/23 Javascript
Angularjs中使用指令绑定点击事件的方法
2017/03/30 Javascript
详谈AngularJs 控制器、数据绑定、作用域
2017/07/09 Javascript
用JS实现简单的登录验证功能
2017/07/28 Javascript
Angular4学习笔记之实现绑定和分包
2017/08/01 Javascript
全选复选框JavaScript编写小结(附代码)
2017/08/16 Javascript
JS库之Particles.js中文开发手册及参数详解
2017/09/13 Javascript
vue click.stop阻止点击事件继续传播的方法
2018/09/04 Javascript
javascript中正则表达式语法详解
2020/08/07 Javascript
[02:05:03]完美世界DOTA2联赛循环赛 LBZS VS Matador BO2 10.28
2020/10/28 DOTA
[51:53]DOTA2-DPC中国联赛 正赛 RNG vs Dragon BO3 第二场 1月24日
2021/03/11 DOTA
Windows下用py2exe将Python程序打包成exe程序的教程
2015/04/08 Python
Python sys.argv用法实例
2015/05/28 Python
WiFi云数码相框:Nixplay
2018/07/05 全球购物
Servlet如何得到客户端机器的信息
2014/10/17 面试题
一份报关员的职业规划范文
2014/01/08 职场文书
简历的自我评价
2014/02/03 职场文书
大专会计自我鉴定
2014/02/06 职场文书
企业员工培训感言
2014/02/26 职场文书
小学生纪念九一八事变演讲稿
2014/09/14 职场文书
项目合作意向书
2015/05/08 职场文书
Python趣味挑战之给幼儿园弟弟生成1000道算术题
2021/05/28 Python
Python排序算法之插入排序及其优化方案详解
2021/06/11 Python