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求素数示例分享
Feb 16 Python
Python实现PS图像调整颜色梯度效果示例
Jan 25 Python
用Python写脚本,实现完全备份和增量备份的示例
Apr 29 Python
Django重置migrations文件的方法步骤
May 01 Python
使用Django开发简单接口实现文章增删改查
May 09 Python
python 实现创建文件夹和创建日志文件的方法
Jul 07 Python
Django实现发送邮件找回密码功能
Aug 12 Python
python判断单向链表是否包括环,若包含则计算环入口的节点实例分析
Oct 23 Python
numpy实现神经网络反向传播算法的步骤
Dec 24 Python
Python MySQLdb 执行sql语句时的参数传递方式
Mar 04 Python
python plt可视化——打印特殊符号和制作图例代码
Apr 17 Python
Python word文本自动化操作实现方法解析
Nov 05 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
改写ThinkPHP的U方法使其路由下分页正常
2014/07/02 PHP
php实现阳历阴历互转的方法
2015/10/28 PHP
PHP基本语法实例总结
2016/09/09 PHP
PHP开启目录引索+fancyindex漂亮目录浏览带搜索功能
2019/09/23 PHP
一个对于js this关键字的问题
2007/01/09 Javascript
Jquery.TreeView结合ASP.Net和数据库生成菜单导航条
2010/08/27 Javascript
网页整体变灰白色(兼容各浏览器)实例
2013/04/21 Javascript
三种取消选中单选框radio的方法
2014/09/09 Javascript
JQuery自适应窗口大小导航菜单附源码下载
2015/09/01 Javascript
JS Attribute属性操作详解
2016/05/19 Javascript
原生js实现淘宝购物车功能
2020/06/23 Javascript
基于jQuery实现数字滚动效果
2017/01/16 Javascript
Angularjs为ng-click事件传递参数
2017/06/15 Javascript
浅谈Vue响应式(数组变异方法)
2018/05/07 Javascript
详解angular分页插件tm.pagination二次触发问题解决方案
2018/07/20 Javascript
详解javascript 变量提升(Hoisting)
2019/03/12 Javascript
js图片无缝滚动插件使用详解
2020/05/26 Javascript
layui+jquery支持IE8的表格分页方法
2019/09/28 jQuery
js实现贪吃蛇小游戏
2019/10/29 Javascript
js闭包的9个使用场景
2020/12/29 Javascript
[53:15]2018DOTA2亚洲邀请赛3月29日 小组赛A组 LGD VS TNC
2018/03/30 DOTA
利用Python绘制MySQL数据图实现数据可视化
2015/03/30 Python
python print 按逗号或空格分隔的方法
2018/05/02 Python
python读取Excel表格文件的方法
2019/09/02 Python
Python 切分数组实例解析
2019/11/07 Python
Django数据库操作之save与update的使用
2020/04/01 Python
如何实现在jupyter notebook中播放视频(不停地展示图片)
2020/04/23 Python
python实现数据结构中双向循环链表操作的示例
2020/10/09 Python
西班牙手机之家:Phone House
2018/10/18 全球购物
大学生自荐书范文
2013/12/10 职场文书
物业公司采购员岗位职责
2013/12/31 职场文书
建筑项目策划书
2014/01/13 职场文书
优秀大学生自荐信
2014/06/09 职场文书
2016年优秀班主任先进事迹材料
2016/02/26 职场文书
请假条应该怎么写?
2019/06/24 职场文书
OpenCV-Python实现轮廓拟合
2021/06/08 Python