最近需要使用 python3 多线程处理大型数据,顺道探究了一下,python3 的线程模型的情况,下面进行简要记录;

多线程运行的优点:

  • 使用线程可以把程序中占用时间较长的任务放到后台去处理;
  • 用户界面可以更加吸引人,并且不阻塞界面的运行;
  • 程序运行的速度可以更快;
  • 充分利用CPU多核的特征进行处理;

内核线程:由操作系统内核创建和撤销;

用户线程:不需要内核支持在用户程序中实现的线程;

Python3 中的多线程:

  • _thread 提供了一些原始的api 用于写多线程程序;
  • threading 提供了更加便利的接口
  • 两者都是python3内置的线程模块
#!/usr/bin/env python

import _thread

def print_time( threadName, delay):
print (threadName)
count =
while :
pass
count += try:
_thread.start_new_thread( print_time, ("Thread-1", , ) )
_thread.start_new_thread( print_time, ("Thread-2", , ) )
_thread.start_new_thread( print_time, ("Thread-3", , ) )
_thread.start_new_thread( print_time, ("Thread-4", , ) )
_thread.start_new_thread( print_time, ("Thread-5", , ) )
_thread.start_new_thread( print_time, ("Thread-6", , ) )
_thread.start_new_thread( print_time, ("Thread-7", , ) )
_thread.start_new_thread( print_time, ("Thread-8", , ) )
_thread.start_new_thread( print_time, ("Thread-9", , ) )
_thread.start_new_thread( print_time, ("Thread-10", , ) )
_thread.start_new_thread( print_time, ("Thread-11", , ) )
_thread.start_new_thread( print_time, ("Thread-12", , ) )
_thread.start_new_thread( print_time, ("Thread-13", , ) )
_thread.start_new_thread( print_time, ("Thread-14", , ) )
_thread.start_new_thread( print_time, ("Thread-15", , ) ) except:
print ("Error: can't start thread!") while :
pass

_thread测试

#!/usr/bin/env python3

import threading
import time exitFlag = class myThread (threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print ("start" + self.name)
print_time(self.name, self.counter, )
print ("exit" + self.name) def print_time(threadName, delay, counter):
while counter:
if exitFlag:
threadName.exit()
time.sleep(delay)
print ("%s: %s" % (threadName, time.ctime(time.time())))
counter -= thread1 = myThread(, "Thread-1", )
thread2 = myThread(, "Thread-2", ) thread1.start()
thread2.start()
thread1.join()
thread2.join() print ("exit!")

threading测试

python 的多线程 threading 有时候并不是特别理想. 最主要的原因是就是, Python 的设计上, 有一个必要的环节, 就是Global Interpreter Lock (GIL). 这个东西让 Python 还是一次性只能处理一个东西:

尽管Python完全支持多线程编程, 但是解释器的C语言实现部分在完全并行执行时并不是线程安全的。 实际上,解释器被一个全局解释器锁保护着,它确保任何时候都只有一个Python线程执行。 GIL最大的问题就是Python的多线程程序并不能利用多核CPU的优势 (比如一个使用了多个线程的计算密集型程序只会在一个单CPU上面运行); 如果要进行利用python的多进程形式,可以使用python的 multiprocessing 编程模型包;

GIL只会影响到那些严重依赖CPU的程序(比如计算型的)。 如果你的程序大部分只会涉及到I/O,比如网络交互,那么使用多线程就很合适, 因为它们大部分时间都在等待;

import threading
from queue import Queue
import copy
import time def job(l, q):
res = sum(l)
q.put(res) def multithreading(l):
q = Queue()
threads = []
for i in range():
t = threading.Thread(target=job, args=(copy.copy(l), q), name='T%i' % i)
t.start()
threads.append(t)
[t.join() for t in threads]
total =
for _ in range():
total += q.get()
print(total) def normal(l):
total = sum(l)
print(total) if __name__ == '__main__':
l = list(range())
s_t = time.time()
normal(l*)
print('normal: ',time.time()-s_t)
s_t = time.time()
multithreading(l)
print('multithreading: ', time.time()-s_t)

GIL测试

#!/usr/bin/env python

import multiprocessing as mp
import threading as td def job(a,b):
while :
pass t1 = td.Thread(target=job,args=(,))
t2 = td.Thread(target=job,args=(,))
t3 = td.Thread(target=job,args=(,))
t4 = td.Thread(target=job,args=(,))
t5 = td.Thread(target=job,args=(,))
t6 = td.Thread(target=job,args=(,))
t7 = td.Thread(target=job,args=(,))
t8 = td.Thread(target=job,args=(,))
t9 = td.Thread(target=job,args=(,))
t10 = td.Thread(target=job,args=(,))
t11 = td.Thread(target=job,args=(,))
t12 = td.Thread(target=job,args=(,))
t13 = td.Thread(target=job,args=(,))
t14 = td.Thread(target=job,args=(,))
t15 = td.Thread(target=job,args=(,))
t16 = td.Thread(target=job,args=(,))
# p1 = mp.Process(target=job,args=(,))
# p2 = mp.Process(target=job,args=(,))
# p3 = mp.Process(target=job,args=(,))
# p4 = mp.Process(target=job,args=(,))
# p5 = mp.Process(target=job,args=(,))
# p6 = mp.Process(target=job,args=(,))
# p7 = mp.Process(target=job,args=(,))
# p8 = mp.Process(target=job,args=(,))
# p9 = mp.Process(target=job,args=(,))
# p10 = mp.Process(target=job,args=(,))
# p11 = mp.Process(target=job,args=(,))
# p12 = mp.Process(target=job,args=(,))
# p13 = mp.Process(target=job,args=(,))
# p14 = mp.Process(target=job,args=(,))
# p15 = mp.Process(target=job,args=(,))
# p16 = mp.Process(target=job,args=(,)) t1.start()
t2.start()
t3.start()
t4.start()
t5.start()
t6.start()
t7.start()
t8.start()
t9.start()
t10.start()
t11.start()
t12.start()
t13.start()
t14.start()
t15.start()
t16.start()
# p1.start()
# p2.start()
# p3.start()
# p4.start()
# p5.start()
# p6.start()
# p7.start()
# p8.start()
# p9.start()
# p10.start()
# p11.start()
# p12.start()
# p13.start()
# p14.start()
# p15.start()
# p16.start()
t1.join()
t2.join()
t3.join()
t4.join()
t5.join()
t6.join()
t7.join()
t8.join()
t9.join()
t10.join()
t11.join()
t12.join()
t13.join()
t14.join()
t15.join()
t16.join()
# p1.join()
# p2.join()
# p3.join()
# p4.join()
# p5.join()
# p6.join()
# p7.join()
# p8.join()
# p9.join()
# p10.join()
# p11.join()
# p12.join()
# p13.join()
# p14.join()
# p15.join()
# p16.join()

跑满你的CPU process vs thread (以16线程CPU为例)

使用python multiprocess 包能够发挥多核CPU并行处理能力

  • multiprocess 接口和threading 使用的接口一样;

并发控制:

  • 进程锁: mp.Lock(), mp.acquire(), mp.release()
  • 线程锁: td.Lock(), td.acquire(), td.release()
  • python 为了提高可用性,保证了multiprocessing 和 threading 中,大多数接口使用都是相同的,较为方便;
  • 多cpu之间,通过共享内存交流;mp.Value('i', 0)
  • 输出队列:mp.Queue() 而 线程之间可以共享内存,可以直接使用 from queue import Queue 来进行引入队列进行使用;

保持更新,转载请注明出处,更多内容请关注cnblogs.com/xuyaowen;

参考链接:

https://morvanzhou.github.io/tutorials/python-basic/threading/5-GIL/

https://python3-cookbook.readthedocs.io/zh_CN/latest/c12/p09_dealing_with_gil_stop_worring_about_it.html  (Python Cookbook 3rd Edition Documentation)

https://morvanzhou.github.io/tutorials/python-basic/multiprocessing/2-add/

Python 3 线程模型,进程模型记录的更多相关文章

  1. Python之线程、进程和协程

    python之线程.进程和协程 目录: 引言 一.线程 1.1 普通的多线程 1.2 自定义线程类 1.3 线程锁 1.3.1 未使用锁 1.3.2 普通锁Lock和RLock 1.3.3 信号量(S ...

  2. Python 中线程和进程

    目录 线程和进程 一. 什么是进程 / 线程 1. 引论 2. 线程 3. 进程 4. 区别 5. 使用 二. 多线程使用 1. 常用方法 2. 常用参数 3. 多线程的应用 3.1 重写线程法 3. ...

  3. Python之线程与进程

    今天我们来了解一下Python的线程和进程的管理机制 首先,我们要了解下线程跟进程的概念: 线程(Thread)是操作系统能够进行运算调度的最小的单位,是一堆cpu的指令.他被包含在进程中,是进程中的 ...

  4. 操作系统/应用程序、操作中的“并发”、线程和进程,python中线程和进程(GIL锁),python线程编写+锁

    并发编程前言: 1.网络应用 1)爬虫 直接应用并发编程: 2)网络框架 django flask tornado 源码-并发编程 3)socketserver 源码-并发编程 2.运维领域 1)自动 ...

  5. python中线程和进程的简单了解

    python中线程和进程的简单了解   一.操作系统.应用程序 1.硬件:硬盘.cpu.主板.显卡........ 2.装系统(本身也是一个软件): 系统就是一个由程序员写出来的软件,该软件用于控制计 ...

  6. Python菜鸟之路:Python基础-线程、进程、协程

    上节内容,简单的介绍了线程和进程,并且介绍了Python中的GIL机制.本节详细介绍线程.进程以及协程的概念及实现. 线程 基本使用 方法1: 创建一个threading.Thread对象,在它的初始 ...

  7. Python基础—线程、进程和协程

    今天已是学习Python的第十一天,来干一碗鸡汤继续今天的内容,今天的鸡汤是:超越别人对你的期望.本篇博客主要介绍以下几点内容: 线程的基本使用: 线程的锁机制: 生产者消费之模型(队列): 如何自定 ...

  8. Python自动化 【第九篇】:Python基础-线程、进程及python GIL全局解释器锁

    本节内容: 进程与线程区别 线程 a)  语法 b)  join c)  线程锁之Lock\Rlock\信号量 d)  将线程变为守护进程 e)  Event事件 f)   queue队列 g)  生 ...

  9. python 四——线程、进程、协程

    内容概要 1.进程与线程优.缺点的比较 2.适用情况 3.线程 线程的创建 setDaemon join event RLock 队列 4.进程 创建进程 setDaemon join 线程与进程,数 ...

  10. python之线程和进程(并发编程)

    python的GIL In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native ...

随机推荐

  1. DRF单表序列化和反序列化

    安装 djangorestframework pip install djangorestframework 将rest_framework注册到app上 INSTALLED_APPS = [ 're ...

  2. IT兄弟连 HTML5教程 CSS3属性特效 3D变换3

    5  3D旋转 在三维变形中,我们可以让元素在任何轴旋转.为此,CSS3新增了三个旋转函数:rotateX().rotateY()和rotateZ().使用rotateX()函数允许一个元素围绕X轴旋 ...

  3. 使用 ASP.NET Core MVC 创建 Web API——响应数据的内容协商(七)

    使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...

  4. 解决方案:从网站下载Excel,我的Office 2016,打开excel文件,显示空白

    今天在写Excel导出案例demo的时候发现,Excel下载后打开空白,要打开了看到空白后再点击一次打开后才可以显示,效果就如下图所示: 那么我就不能一次打开吗?我找了半天最终在这个博客找到了答案:h ...

  5. python基础(36):pymysql模块

    1. pymysql模块 在使用pymysql模块前需要学习数据库MySQL:<MySQL基础>. 1.1 pymysql的下载和使用 看完MySQL基础,我们都是通过MySQL自带的命令 ...

  6. js 回调地狱的另类解决方案尝试

    例如 通过学生获取学生所在学校信息,需要先查询学生所在班级,再通过班级查询所在学校信息.js代码类似写法如下: function getStudentSchool(id) { ajax.get(&qu ...

  7. 控制台提示“Invalid string length”的原因

    控制台提示“Invalid string length”,浏览器直接卡掉,是为什么呢? 答:因为在写嵌套循环时,定义的变量重名了,内层和外层用了同一个i变量. -THE END-

  8. GPS定位的偏移校正(WGS84与火星坐标互转)

    地图坐标系目前包括: 地球坐标 (WGS84) WGS84:World Geodetic System 1984,是为GPS全球定位系统使用而建立的坐标系统. 国际标准,从 GPS 设备中取出的数据的 ...

  9. 头条小视频和西瓜视频signature签名算法

    点击上方↑↑↑蓝字[协议分析与还原]关注我们 "分析今日头条内小视频和西瓜视频分享后浏览器打开所用的signature签名算法." 上月写的一篇关于使用微信的wxid加好友的文章, ...

  10. Android 无源码smail进行debug

    待调试项目在AndroidManifest.xml中debugable=true 参照此处:https://blog.csdn.net/ausboyue/article/details/8018918 ...