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中使用异步Socket编程性能测试
Jun 25 Python
python实现简单购物商城
May 21 Python
详解Python3中字符串中的数字提取方法
Jan 14 Python
Python爬虫设置代理IP的方法(爬虫技巧)
Mar 04 Python
Python实现的简单计算器功能详解
Aug 25 Python
由Python编写的MySQL管理工具代码实例
Apr 09 Python
Django网络框架之创建虚拟开发环境操作示例
Jun 06 Python
ZABBIX3.2使用python脚本实现监控报表的方法
Jul 02 Python
Django xadmin开启搜索功能的实现
Nov 15 Python
Pytorch转keras的有效方法,以FlowNet为例讲解
May 26 Python
用 Python 定义 Schema 并生成 Parquet 文件详情
Sep 25 Python
Appium中scroll和drag_and_drop根据元素位置滑动
Feb 15 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 addslashes()与addclashes()函数的区别和比较
2013/06/24 PHP
php版微信数据统计接口用法示例
2016/10/12 PHP
php swoft框架实例用法
2020/12/22 PHP
extjs ColumnChart设置不同的颜色实现代码
2013/05/17 Javascript
使用Jquery获取带特殊符号的ID 标签的方法
2014/04/30 Javascript
jquery比较简洁的软键盘特效实现方法
2015/03/19 Javascript
jquery实现键盘左右翻页特效
2015/04/30 Javascript
使用Ajax与服务器(JSON)通信实例
2016/11/04 Javascript
js代码延迟一定时间后执行一个函数的实例
2017/02/15 Javascript
vue如何引用其他组件(css和js)
2017/04/13 Javascript
微信通过页面(H5)直接打开本地app的解决方法
2017/09/09 Javascript
JavaScript实现获取两个排序数组的中位数算法示例
2019/02/26 Javascript
详解vue2.6插槽更新v-slot用法总结
2019/03/09 Javascript
[57:29]Alliance vs KG 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/17 DOTA
[03:15]DOTA2-DPC中国联赛1月22日Recap集锦
2021/03/11 DOTA
windows下安装python paramiko模块的代码
2013/02/10 Python
在Python的Flask框架中实现单元测试的教程
2015/04/20 Python
在DigitalOcean的服务器上部署flaskblog应用
2015/12/19 Python
实例讲解Python设计模式编程之工厂方法模式的使用
2016/03/02 Python
python 在指定范围内随机生成不重复的n个数实例
2019/01/28 Python
python3爬取torrent种子链接实例
2020/01/16 Python
Python接口测试数据库封装实现原理
2020/05/09 Python
html5启动原生APP总结
2020/07/03 HTML / CSS
红色康乃馨酒店:Red Carnation Hotels
2017/06/22 全球购物
印尼网上商店:Alfacart.com
2019/03/11 全球购物
英国卫浴商店:Ergonomic Design
2019/09/22 全球购物
俄罗斯童装网上商店:BebaKids
2020/06/06 全球购物
Linden Leaves官网:新西兰纯净护肤品
2020/12/20 全球购物
什么是Remote Module
2016/06/10 面试题
土建资料员岗位职责
2014/01/04 职场文书
国家励志奖学金获奖感言
2014/01/09 职场文书
团代会主持词
2014/04/02 职场文书
优秀安全员事迹材料
2014/05/11 职场文书
护士求职信
2014/07/05 职场文书
群教个人对照检查材料
2014/08/20 职场文书
Win11 S Mode版本泄露 正式上线后叫做Windows 11 SE
2021/11/21 数码科技