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 ...
随机推荐
- iNeuOS工业互联平台,聚合和变化率计算、设备IO和通讯状态、组态快捷键、创建文件夹、选择应用图标等,发布:v3.6版本
目 录 1. 概述... 2 2. 平台演示... 2 3. 聚合和变化率计算... 2 4. 设备IO和通讯状态监测... 3 5. 组 ...
- QT 自定义控件 以及信号和槽的使用
自定义login 控件 Login头文件 #ifndef LOGIN_H #define LOGIN_H #include <QWidget> namespace Ui { class L ...
- vsftpd - FTP 服务器安装
由于要将本地程序上传至云服务器中,所以需要给云服务器端安装ftp服务器.记录一下ftp的安装过程,以便以后使用.服务器端所用系统为Ubuntu16.04. 1. 安装ftp服务器, apt-get i ...
- 【springcloud】一文带你搞懂API网关
作者:aCoder2013 https://github.com/aCoder2013/blog/issues/35 前言 假设你正在开发一个电商网站,那么这里会涉及到很多后端的微服务,比如会员.商品 ...
- ProjectEuler 007题
题目:By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is ...
- String与Int类型的转换
http://blog.sina.com.cn/s/blog_4f9d6b1001000bfo.html int -> String int i=12345; String s="&q ...
- mybatis gengeator一键生成
- Spring笔记(1)
Spring快速入门 开发步骤 导入坐标 <dependency> <groupId>org.springframework</groupId> <artif ...
- 如何在C#中打开和读取EXCEL文件
这篇文章向您展示如何在C#Windows Forms Application中使用ExcelDataReader,ExcelDataReader.DataSet打开和读取Excel文件.创建一个新的W ...
- JDBC管理事务
一.事务概念:打包一起的多个步骤的业务操作,要么同事成功,要么同时失败,则需要用事务管理: 二.代码实现