最近需要使用 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. webpack生成的css文件background-image url图片无法加载

    之前在使用webpack3构建基于less预处理的项目时,在对指定的元素使用background-image: url(xxx)来设置背景图片时,本地开发是ok的,但是在项目编译产出后背景图片就找不到 ...

  2. YII2中andWhere多个or查询

    使用多个or的复杂查询: AND ((`name`='张三') OR (`name`='李四') OR (`name`='王五')) // AND ((`name`='张三') OR (`name`= ...

  3. IT兄弟连 HTML5教程 CSS3属性特效 弹性盒模型

    CSS3引入了新的盒模型——弹性盒模型,该模型决定一个盒子在其他盒子中的分布方式以及如何处理可用的空间.使用该模型,可以很轻松的创建自适应浏览器窗口的流动布局或自适应字体大小的弹性布局.弹性盒模型看起 ...

  4. linux的常用命令(一)

    目录切换命令: cd切换目录 cd /usr 切换到usr目录 cd ..     切换到上一层目录 cd ../..   调到当前目录的上上两层 cd  /      切换到系统根目录 cd  ~  ...

  5. 【每天一题】LeetCode 0026. 删除排序数组中的重复项

    开源地址:https://github.com/jiauzhang/algorithms 题目描述 /* * https://leetcode-cn.com/problems/remove-dupli ...

  6. C# Monitor and transfer or copy the changed or created file to a new location

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Tex ...

  7. ASP.NET底层原理

    上图基本上演示了IIS 6整个处理过程.在User Mode下,http.sys接收到一个基于aspx的http request,然后它会根据IIS中的Metabase查看该基于该Request的Ap ...

  8. uni-app ios 苹果真机运行

    首先我们准备苹果手机一台,数据线一根,然后连接到电脑. 1.电脑安装iTunes 软件,网址:http://soft.onlinedown.net/soft/279734.htm 安装完成之后打开iT ...

  9. 更新阿里yum源并重建缓存

    [第一种方式]1.下载安装wget /如果没有装的话yum install -y wget 2.备份默认的yummv /etc/yum.repos.d /etc/yum.repos.d.backup ...

  10. RMAN RECOVER TABLE 功能是 Oracle Database 12c 的新增功能 (Doc ID 1521524.1)

    RMAN RECOVER TABLE Feature New to Oracle Database 12c (Doc ID 1521524.1) APPLIES TO: Oracle Database ...