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的判断语句模拟三目运算
Apr 24 Python
让python 3支持mysqldb的解决方法
Feb 14 Python
Python 专题一 函数的基础知识
Mar 16 Python
python 2.7.14安装图文教程
Apr 08 Python
Python简单实现的代理服务器端口映射功能示例
Apr 08 Python
python使用folium库绘制地图点击框
Sep 21 Python
Python多叉树的构造及取出节点数据(treelib)的方法
Aug 09 Python
使用OpenCV实现仿射变换—缩放功能
Aug 29 Python
解决Tensorflow 使用时cpu编译不支持警告的问题
Feb 03 Python
解决pyCharm中 module 调用失败的问题
Feb 12 Python
python Django 反向访问器的外键冲突解决
May 20 Python
使用pycharm运行flask应用程序的详细教程
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
使用数据库保存session的方法
2006/10/09 PHP
php 函数中使用static的说明
2012/06/01 PHP
深入理解ob_flush和flush的区别(ob_flush()与flush()使用方法)
2013/02/06 PHP
解析php中mysql_connect与mysql_pconncet的区别详解
2013/05/15 PHP
set_exception_handler函数在ThinkPHP中的用法
2014/10/31 PHP
php+mysql查询优化简单实例
2015/01/13 PHP
php基于SQLite实现的分页功能示例
2017/06/21 PHP
jQuery 剧场版 你必须知道的javascript
2009/05/27 Javascript
JQuery 学习笔记 element属性控制
2009/07/23 Javascript
jQuery数组处理代码详解(含实例演示)
2012/02/03 Javascript
如何通过javascript操作web控件的自定义属性
2013/11/25 Javascript
JS实现在状态栏显示打字效果完整实例
2015/11/02 Javascript
jQuery mobile 移动web(4)
2015/12/20 Javascript
javascript 利用arguments实现可变长参数
2016/11/21 Javascript
概述一个页面从输入URL到页面加载完的过程
2016/12/16 Javascript
详解nodejs微信公众号开发——4.自动回复各种消息
2017/04/11 NodeJs
使用FileReader API创建Vue文件阅读器组件
2018/04/03 Javascript
Vue 实现树形视图数据功能
2018/05/07 Javascript
Vue实现移动端左右滑动效果的方法
2018/11/27 Javascript
Javascript三种字符串连接方式及性能比较
2019/05/28 Javascript
vue+ElementUI 关闭对话框清空验证,清除form表单的操作
2020/08/06 Javascript
[03:56]还原FTP电影首映式 DOTA2群星拼出遗迹世界
2014/03/26 DOTA
Django中的CACHE_BACKEND参数和站点级Cache设置
2015/07/23 Python
Python的条件表达式和lambda表达式实例
2019/01/31 Python
HTML5+CSS3实现拖放(Drag and Drop)示例
2014/07/07 HTML / CSS
HTML5拖放API实现拖放排序的实例代码
2017/05/11 HTML / CSS
Dillard’s百货官网:Dillards.com
2018/05/26 全球购物
八一建军节部队活动方案
2014/02/04 职场文书
一句话工作感言
2014/03/01 职场文书
学习雷锋倡议书
2014/04/15 职场文书
团支书竞选演讲稿
2014/04/28 职场文书
小学数学教学经验交流材料
2014/05/22 职场文书
出售房屋协议书范本
2014/10/06 职场文书
商务英语求职信范文
2015/03/19 职场文书
酒店工程部的岗位职责汇总大全
2019/10/23 职场文书
MongoDB使用场景总结
2022/02/24 MongoDB