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 实现文件的递归拷贝实现代码
Aug 02 Python
Python中使用Boolean操作符做真值测试实例
Jan 30 Python
Python使用pymysql小技巧
Jun 04 Python
Python实现删除列表中满足一定条件的元素示例
Jun 12 Python
基于numpy.random.randn()与rand()的区别详解
Apr 17 Python
python中的tcp示例详解
Dec 09 Python
用Python将结果保存为xlsx的方法
Jan 28 Python
Python for i in range ()用法详解
Sep 18 Python
基于Numba提高python运行效率过程解析
Mar 02 Python
Python操作PostgreSql数据库的方法(基本的增删改查)
Dec 29 Python
浅谈pytorch中的dropout的概率p
May 27 Python
python index() 与 rindex() 方法的使用示例详解
Dec 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 session处理的定制
2009/03/16 PHP
php5.3 废弃函数小结
2010/05/16 PHP
php ci 获取表单中多个同名input元素值的代码
2016/03/25 PHP
PHP入门教程之会话控制技巧(cookie与session)
2016/09/11 PHP
php中照片旋转 (orientation) 问题的正确处理
2017/02/16 PHP
kindeditor 加入七牛云上传的实例讲解
2017/11/12 PHP
Js,alert出现乱码问题的解决方法
2013/06/19 Javascript
js获取触发事件元素在整个网页中的绝对坐标(示例代码)
2013/12/13 Javascript
js中继承的几种用法总结(apply,call,prototype)
2013/12/26 Javascript
javascript事件冒泡详解和捕获、阻止方法
2014/04/12 Javascript
使用jquery写个更改表格行顺序的小功能
2014/04/29 Javascript
js和jquery设置disabled属性为true使按钮失效
2014/08/07 Javascript
EasyUI布局 高度自适应
2016/06/04 Javascript
node前端模板引擎Jade之标签的基本写法
2018/05/11 Javascript
原生js代码能实现call和bind吗
2019/07/31 Javascript
Vue 实现从小到大的横向滑动效果详解
2019/10/16 Javascript
[02:29]DOTA2英雄基础教程 陈
2013/12/17 DOTA
Python文件处理
2016/02/29 Python
在pandas中一次性删除dataframe的多个列方法
2018/04/10 Python
详解Python if-elif-else知识点
2018/06/11 Python
PyQT5 QTableView显示绑定数据的实例详解
2019/06/25 Python
python base64库给用户名或密码加密的流程
2020/01/02 Python
Python中logger日志模块详解
2020/08/04 Python
全天然狗零食:Best Bully Sticks
2016/09/22 全球购物
澳大利亚著名的纺织品品牌:Canningvale
2020/05/05 全球购物
C语言笔试题
2014/09/04 面试题
商得四方公司面试题(gid+)
2014/04/30 面试题
应届医学毕业生求职信分享
2013/12/02 职场文书
竞聘副主任科员演讲稿
2014/01/11 职场文书
婚礼主持词
2014/03/13 职场文书
中职三好学生事迹材料
2014/08/24 职场文书
个人委托函范文
2015/01/29 职场文书
教师考核表个人总结
2015/02/12 职场文书
简历中自我评价范文
2015/03/11 职场文书
2015年学校食堂工作总结
2015/04/22 职场文书
Python与C++中梯度方向直方图的实现
2022/03/17 Python