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使用MONGODB入门实例
May 11 Python
Python自动发邮件脚本
Mar 31 Python
Python正则表达式完全指南
May 25 Python
Python及PyCharm下载与安装教程
Nov 18 Python
Python获取当前公网ip并自动断开宽带连接实例代码
Jan 12 Python
修复CentOS7升级Python到3.6版本后yum不能正确使用的解决方法
Jan 26 Python
TensorFlow实现RNN循环神经网络
Feb 28 Python
对sklearn的使用之数据集的拆分与训练详解(python3.6)
Dec 14 Python
numpy基础教程之np.linalg
Feb 12 Python
Python 过滤错误log并导出的实例
Dec 26 Python
Python爬虫爬取微信朋友圈
Aug 06 Python
python和C/C++混合编程之使用ctypes调用 C/C++的dll
Apr 29 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
其他功能
2006/10/09 PHP
用 Composer构建自己的 PHP 框架之设计 MVC
2014/10/30 PHP
ThinkPHP里用U方法调用js文件实例
2015/06/18 PHP
功能强大的php文件上传类
2016/08/29 PHP
jquery动画1.加载指示器
2012/08/24 Javascript
js页面跳转的常用方法整理
2013/10/18 Javascript
设为首页和收藏的Javascript代码(亲测兼容IE,Firefox,chrome等浏览器)
2013/11/18 Javascript
仅一个form表单 js实现注册信息依次填写提交功能
2016/06/12 Javascript
jQuery如何封装输入框插件
2016/08/19 Javascript
AngularJS中$http使用的简单介绍
2017/03/17 Javascript
Vue.js实例方法之生命周期详解
2017/07/03 Javascript
JavaScript 基础表单验证示例(纯Js实现)
2017/07/20 Javascript
js学习总结之DOM2兼容处理顺序问题的解决方法
2017/07/27 Javascript
JS实现的简单表单验证功能示例
2017/10/13 Javascript
Js面试算法详解
2018/04/08 Javascript
angularjs实现table表格td单元格单击变输入框/可编辑状态示例
2019/02/21 Javascript
javascript设计模式 ? 外观模式原理与用法实例分析
2020/04/15 Javascript
Layer UI表格列日期格式化及取消自动填充日期的实现方法
2020/05/10 Javascript
js实现批量删除功能
2020/08/27 Javascript
[05:01]3.19DOTA2发布会 我们都是刀塔人
2014/03/25 DOTA
跟老齐学Python之集合(set)
2014/09/24 Python
使用Python从零开始撸一个区块链
2018/03/14 Python
Python 加密与解密小结
2018/12/06 Python
Flask框架重定向,错误显示,Responses响应及Sessions会话操作示例
2019/08/01 Python
Python3.7安装keras和TensorFlow的教程图解
2020/06/18 Python
django和flask哪个值得研究学习
2020/07/31 Python
详解HTML5中的picture元素响应式处理图片
2018/01/03 HTML / CSS
海淘零差价,宝贝全球购: 宝贝格子
2016/08/24 全球购物
世界最大的票务市场:viagogo
2017/02/16 全球购物
Java的接口和C++的虚类的相同和不同处
2014/03/27 面试题
七一表彰活动方案
2014/01/18 职场文书
先进个人事迹材料
2014/01/25 职场文书
读书活动实施方案
2014/03/10 职场文书
村党总支部公开承诺书2016
2016/03/25 职场文书
python APScheduler执行定时任务介绍
2022/04/19 Python
微软发布Windows 11今年最大更新22H2(附 ISO 镜像官方下载)
2022/09/23 数码科技