python多线程与_thread模块
进程与线程
1.进程:计算机程序只是存储在磁盘中的可执行二进制(或其他类型)的文件。只有把他们加载到内存中并被操作系统调用,才具有其生命周期。进程则是一个执行中的程序。每个进程都拥有自己的地址空间,内存,数据栈以及其他用于跟踪执行的辅助数据。进程也可以通过派生新的进程来执行其他任务。由于每个进程有自己的数据,所以只能采用进程间通信(IPC)的方式来共享信息。
2.线程:又称轻量级进程。一个进程开始便会创建一个线程,称为主线程。一个进程可以创建多个线程,多线程即是同一进程下的不同执行路径,同一进程下的线程共享该进程的数据区。线程以并发的方式执行,线程执行时可以被中断和挂起。(在多核cpu中,多线程才可能并行执行)
图解多线程与单线程:单核与多核

线程和python
1.全局解释器锁
python代码执行是由python虚拟机(又称解释器主循环)控制的。python在主循环中同时只能有一个控制线程在执行,就像单核cpu系统中,内存中可以有很多程序,但任意给定时刻只能有一个程序在运行。同理,尽管python解释器可以运行多线程,但在任意给定时刻只有一个线程会被解释器执行。
对python虚拟机由全局解释器锁(GIL)控制。正是由于GIL的存在,python解释器在某一时刻只能让一个线程执行。多线程执行方式如下:
1)设置GIL
2)切换一个线程去执行
3)执行下面操作之一
a.指定数量字节码指令
b.线程让出控制权
4)线程设置成睡眠(挂起)状态
5)解锁GIL
6)重复1-5
2.python多线程的作用,原理,缺陷
作用:提高程序执行速度。
原理:多线程能够提高执行速度的原因是什么?假如一个程序包含多个子任务,这些任务相互独立,没有因果关系。
a.单线程情况下,执行过程中,某个子任务在等待I/O,然而I/O到来的时间不确定,cpu时间耗在毫无意义的等待上,程序执行时间也将加上这一段等待的时间。
b.多线程情况下,若某个子任务等待I/O,可切换出其他线程执行,等到合适的时机(I/O到达)再切换回该线程,避免了cpu无意义的等待,也降低了程序的执行时间。
缺陷:由于GIL的存在,python多线程中只能有一个线程会被执行,因而无法利用多核cpu能够实现并行执行的特点。不仅如此,由于线程的切换需要时间开销,多线程使用不当的程序执行速度还可能要慢于单线程程序执行的速度。
3.python多线程的使用场合
I/O密集型应用
_thread模块
python的_thread模块提供了基本的线程和互斥锁支持,threading模块则提供了功能更全面的线程管理。以下讨论_thread模块
主要方法
_thread.start_new_thread(function,args,kwargs=None) //派生一个新的线程,给定agrs和kwargs来执行function
_thread.allocate_lock() //分配锁对象
_thread.exit() //线程退出
lock.acquire(waitflag=1, timeout=-1) //获取锁对象
lock.locked() //如果获取了锁对象返回true,否则返回false
lock.release() //释放锁
其他方法
_thread.LockType() //锁对象类型
_thread.get_ident() //获取线程标识符
-thread.TIMEOUT_MAX //lock.acquire的最大时间,超时将引发OverflowError
_thread.interrupt_main() //引发主线程KeyboardInterrupt错误,子线程可以用这个函数来终止主线程
简单实例
4个线程分别执行loop函数,中间等待nsec秒,nsec分别为4,2,3,5
1 #!/usr/bin/env python3
2 # coding:utf-8
3 from time import ctime
4 from time import sleep
5 import _thread
6
7 loops = [4, 2, 3, 5]
8
9
10 def loop(nloop, nsec, lock): # 参数依次为:标识,睡眠时间,锁对象
11 print("start loop", nloop, 'at:', ctime())
12 sleep(nsec)
13 print("loop", nloop, "done at:", ctime())
14 lock.release() # 释放锁
15
16
17 def main():
18 print('start at:', ctime())
19 locks = []
20 nloops = range(len(loops))
21
22 for i in nloops:
23 lock = _thread.allocate_lock() # 分配锁对象
24 lock.acquire() # 获取锁对象
25 locks.append(lock)
26
27 for i in nloops:
28 _thread.start_new(loop, (i, loops[i], locks[i])) //派生新线程
29
30 # 等待所有锁被释放
31 for i in nloops:
32 while(locks[i].locked()):
33 pass
34 print('all DONE at', ctime())
35
36
37 if __name__ == '__main__':
38 main()
执行结果:
start at: Mon Jan 22 16:09:10 2018
start loop 2 at: Mon Jan 22 16:09:10 2018
start loop 1 at: Mon Jan 22 16:09:10 2018
start loop 3 at: Mon Jan 22 16:09:10 2018
start loop 0 at: Mon Jan 22 16:09:10 2018
loop 1 done at: Mon Jan 22 16:09:12 2018
loop 2 done at: Mon Jan 22 16:09:13 2018
loop 0 done at: Mon Jan 22 16:09:14 2018
loop 3 done at: Mon Jan 22 16:09:15 2018
all DONE at Mon Jan 22 16:09:15 2018
分别等待4,2,3,5秒,程序运行总时间5秒。main()函数最后一个循环作用是等待所有子线程退出。
注意事项
_thread对于进程何时退出没有任何控制。当主线程结束时,所有其他线程也都强制结束。不会发出警告或者进行适当的清理。因而python多线程一般使用较为高级的threading模块,它提供了完整的线程控制机制以及信号量机制。
可参考:
python多线程与_thread模块的更多相关文章
- python多线程与threading模块
python多线程与_thread模块 中介绍了线程的基本概念以及_thread模块的简单示例.然而,_thread模块过于简单,使得我们无法用它来准确地控制线程,本文介绍threading模块,它提 ...
- python多线程之_thread
多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进 ...
- Python多线程(threading模块)
线程(thread)是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. ...
- python 多线程,tthread模块比较底层,而threading模块是对thread做了一些包装,multithreading
Python多线程详解 2016/05/10 · 基础知识 · 1 评论· 多线程 分享到:20 本文作者: 伯乐在线 - 王海波 .未经作者许可,禁止转载!欢迎加入伯乐在线 专栏作者. 1.多线程的 ...
- python多线程编程-queue模块和生产者-消费者问题
摘录python核心编程 本例中演示生产者-消费者模型:商品或服务的生产者生产商品,然后将其放到类似队列的数据结构中.生产商品中的时间是不确定的,同样消费者消费商品的时间也是不确定的. 使用queue ...
- python 多线程编程之_thread模块
参考书籍:python核心编程 _thread模块除了可以派生线程外,还提供了基本的同步数据结构,又称为锁对象(lock object,也叫原语锁.简单锁.互斥锁.互斥和二进制信号量). 下面是常用的 ...
- 进程,线程,GIL,Python多线程,生产者消费者模型都是什么鬼
1. 操作系统基本知识,进程,线程 CPU是计算机的核心,承担了所有的计算任务: 操作系统是计算机的管理者,它负责任务的调度.资源的分配和管理,统领整个计算机硬件:那么操作系统是如何进行任务调度的呢? ...
- python的_thread模块来实现多线程(<python核心编程例子>)
python中_thread模块是一个低级别的多线程模块,它的问题在于主线程运行完毕后,会立马把子线程给结束掉,不加处理地使用_thread模块是不合适的.这里把书中讲述的有关_thread使用的例子 ...
- python _thread模块使用
python关于线程管理的有2个类,_thread(在2.x的版本中叫thread)和threading. # encoding: UTF-8 import thread import time ...
随机推荐
- Linux搭建SQL server服务器
我们知道在Linux下安装服务有很多方式,最为简单的也就是yum安装,但是很多服务通过yum是无法安装的,如果想使用yum安装,需要指定yum安装仓库,我们今天需要安装MSQL Server,所以需要 ...
- C++继承体系中的内存对齐
本篇随笔讨论一个比较冷门的知识,继承结构中内存对齐的问题,如今内存越来越大也越来越便宜,大部分人都已经不再关注内存对齐的问题了.但是作为一个有追求的技术人员,实现功能永远都是最基本的要求,把代码优化到 ...
- (二)js基础。。。freecodecamp笔记
个人需要注意的点 当 JavaScript 中的变量被声明的时候,程序内部会给它一个初始值undefined.当你对一个值为undefined的变量进行运算操作的时候,算出来的结果将会是NaN,NaN ...
- ubuntu 查看系统信息
1.系统信息 uname -a 显示linux的内核版本和系统是多少位的:X86_64代表系统是64位的. Linux field-ubuntu-18 4.15.0-20-generic #21-Ub ...
- Ajax 与 Struts 1
Xml配置 <action path="/product/product/validateCurrencyDecimalSupport" type="com.neu ...
- python json demo
值得注意的一点是,list类型的数据可以用[2,3]的方式定义,如"b" import json jsonData = '{"a":1,"b" ...
- MySQL双主+Keepalived高可用
原文转自:https://www.cnblogs.com/itzgr/p/10233932.html作者:木二 目录 一 基础环境 二 实际部署 2.1 安装MySQL 2.2 初始化MySQL 2. ...
- D3之svg transform 与 css3 transform 区别与联系
D3就不用多介绍了,在数据可视化界属于大佬级别的js库.在这里主要想记录一下在写程序期间遇到的一个问题. 如下图所示,想完成主视图在小地图上的映射,小地图的白色矩形框用来代表当前主视图可见区域,主视图 ...
- 前缀和的n个神奇操作
前情回顾 前缀和的基础用法戳这里->传送门 众所周知,简单的前缀和解决的一般都是静态查询的问题,例如区间和.区间积等 操作的时候也很简单,就是根据需要来维护一个数组,每次查询的时候就用到tr[r ...
- hyperf从零开始构建微服务(一)——构建服务提供者
阅读目录 什么是服务 构建服务提供者 1.创建数据表 2.构建服务提供者 3.安装json rpc依赖 4.安装rpc server组件 5.修改server配置 6.配置数据库 7.编写基础代码 7 ...