Threading 模块

threading 模块除了提供基本的线程和锁定支持外,还提供了更高级别、功能更全面的线程管理。threading 模块支持守护线程,其工作方式是:守护线程一般是一个等待客户端请求的服务器,如果没有客户端请求,守护线程就是空闲的。如果把一个线程设置为守护线程,就表示这个线程是不重要的,进程退出时不需要等待这个线程完成。(如何设置守护线程?只需执行赋值语句: thread.daemon = True )

threading 模块的对象:

对象 描述
Thread 表示一个执行线程的对象
Lock 锁原语对象(和 thread 模块中的锁一样)
RLock 可重入锁对象,使单一线程可以(再次)获得已持有的锁(锁递归)
Condition 条件变量对象,使得一个线程等待另一个线程满足特定的“条件”,比如改变状态或者某个数据
Event 条件变量的通用版本,任意数量的线程等待某个事件的发生,在该事件发生后所有线程将被激活
Semaphore 为线程间共享的有限资源提供了一个“计数器”,如果没有可用资源时会被阻塞
BoundedSemaphore 与 Semaphore 相似,不过它不允许超过初始值
Timer 与 Thread 相似, 不过它要在运行前等待一段时间
Barrier① 创建一个“障碍”,必须达到指定数量的线程后才可以继续
[①]  Python 3.2版本中引入

Thread 类

threading 模块的 Thread 类是主要的执行对象,它有 thread 模块中没有的很多函数。

Thread 对象的属性和方法:

属性/方法 描述
Thread 对象数据属性  
name 线程名
ident 线程的标识符
daemon 布尔标志,表示这个线程是否是守护线程
Thread 对象方法  
_init_(group=None, tatget=None, name=None, args=(), kwargs={}, verbose=None, daemon=None) 实例化一个线程对象,需要有一个可调用的 target,以及其参数 args 或 kwargs 。还可以传递 name 或 group 参数,不过后者还未实现。此外, verbose 标志也是可接受的。 而 daemon 的值将会设定 thread.daemon 属性/标志
start() 开始执行线程
run() 定义线程功能的方法(通常在子类中被应用开发者重写)
join(timeout=None) 直至启动的线程终止之前一直挂起,除非给出了 timeout (单位为秒),否则会一直阻塞
is_alive() 布尔标志,表示这个线程是否还存活

使用 Thread 类可以有很多种方法创建线程,比如:

  • 创建 Thread 的实例,传给它一个函数;

  • 创建 Thread 的实例,传给它一个可调用的类实例;

  • 派生 Thread 的子类,并创建子类的实例。

    *注:一般选择第一个和第三个,当需要一个更加符合面向对象的接口时选择第三个

创建 Thread 的实例,传给它一个函数

使用 threading 模块(mtsleepC.py):

*注:threading 模块的 Thread 类中有个 join() 方法,可以让主线程等待所有线程执行完毕。

 import threading
from time import sleep, ctime

loops = [4,2]

def loop(nloop, nsec):
print('start loop %s at:%s' % (nloop, ctime()))
sleep(nsec)
print('loop %s done at:%s' % (nloop, ctime()))

def main():
print("starting at:%s" % ctime())
threads = []
nloops = range(len(loops))

for i in nloops:
t = threading.Thread(target=loop, args=(i, loops[i]))
threads.append(t)

for i in nloops:
threads[i].start()

for i in nloops:
threads[i].join()

print('all DONE at:%s' % ctime())


if __name__ == '__main__':
main()

运行后输出结果:

 $ mtsleepC.py
starting at:Mon Jul 23 12:44:48 2018
start loop 0 at:Mon Jul 23 12:44:48 2018
start loop 1 at:Mon Jul 23 12:44:48 2018
loop 1 done at:Mon Jul 23 12:44:50 2018
loop 0 done at:Mon Jul 23 12:44:52 2018
all DONE at:Mon Jul 23 12:44:52 2018

实例化每个 Thread 对象时,把函数(target)和参数(args)传进去,然后得到返回的 Thread 实例。实例化 Thread 和调用 thread.start_new_thread() 的最大区别就是新线程不会立即执行。当所有线程分配完后,通过调用每个线程的 start() 方法让他们开始执行。join() 方法将等待线程结束,或者超过提供的时间自动结束。对 join() 方法而言,它根本不需要调用,一旦线程启动它就会一直执行,直到给定的函数完成后退出。

创建 Thread 的实例,传给它一个可调用的类实例

使用可调用的类(mtsleepD.py):

*注:本例中将传递进去一个可调用类(实例)而不仅仅是一个函数。提供了更加面向对象的方法

 import threading
from time import sleep, ctime

loops = [4,2]

class ThreadFunc(object):

def __init__(self, func, args, name=''):
self.name = name
self.func = func
self.args = args

def __call__(self):
self.func(*self.args)

def loop(nloop, nsec):
print('start loop %s at:%s' % (nloop, ctime()))
sleep(nsec)
print('loop %s done at:%s' % (nloop, ctime()))

def main():
print('starting at:%s' % ctime())
threads = []
nloops = range(len(loops))

for i in nloops: # 创建所有线程
t = threading.Thread(
target=ThreadFunc(loop, (i, loops[i]),loop.__name__)
)
threads.append(t)

for i in nloops: # 启动所有线程
threads[i].start()

for i in nloops: # 等待结束
threads[i].join()

print('all DONE at:%s' % ctime())


if __name__ == '__main__':
main()

运行后的输出结果:

 $ mtsleepD.py
starting at:Tue Jul 24 09:02:32 2018
start loop 0 at:Tue Jul 24 09:02:32 2018
start loop 1 at:Tue Jul 24 09:02:32 2018
loop 1 done at:Tue Jul 24 09:02:34 2018
loop 0 done at:Tue Jul 24 09:02:36 2018
all DONE at:Tue Jul 24 09:02:36 2018
派生 Thread 的子类,并创建子类的实例

子类化的 Thread(mtsleepE.py):

*注:本例中将对 Thread 子类化,而不是直接对其实例化。这将使我们在定制线程对象时拥有更多灵活性,也能够简化线程创建的调用过程。

 import threading
from time import sleep, ctime

loops = [4,2]

class MyThread(threading.Thread):

def __init__(self, func, args, name=''):
threading.Thread.__init__(self)
self.name = name
self.func = func
self.args = args

def run(self):
self.func(*self.args)

def loop(nloop, nsec):
print('start loop %s at:%s' % (nloop, ctime()))
sleep(nsec)
print('loop %s done at:%s' % (nloop, ctime()))

def main():
print('starting at:%s' % ctime())
threads = []
nloops = range(len(loops))

for i in nloops: # 创建所有线程
t = MyThread(loop, (i, loops[i]), loop.__name__)
threads.append(t)

for i in nloops: # 启动所有线程
threads[i].start()

for i in nloops: # 等待结束
threads[i].join()

print('all DONE at:%s' % ctime())


if __name__ == '__main__':
main()

运行后的输出结果:

 $ mtsleepE.py
starting at:Tue Jul 24 09:13:49 2018
start loop 0 at:Tue Jul 24 09:13:49 2018
start loop 1 at:Tue Jul 24 09:13:49 2018
loop 1 done at:Tue Jul 24 09:13:51 2018
loop 0 done at:Tue Jul 24 09:13:53 2018
all DONE at:Tue Jul 24 09:13:53 2018

threading 模块的其它函数

函数 描述
active_count() 当前活动的 Thread 对象个数
current_thread 返回当前活动的 Thread 对象
enumerate() 返回当前活动的 Thread 对象列表
settrace(func) 为所有线程设置一个 trace 函数
setprofile(func) 为所有线程设置一个 profile 函数
stack_size(size=0) 返回新创建线程的栈大小;或为后续创建的线程设定栈的大小为 size

threading模块—Python多线程编程的更多相关文章

  1. Python:使用threading模块实现多线程编程

    转:http://blog.csdn.net/bravezhe/article/details/8585437 Python:使用threading模块实现多线程编程一[综述] Python这门解释性 ...

  2. thread模块—Python多线程编程

    Thread 模块 *注:在实际使用过程中不建议使用 thread 进行多线程编程,本文档只为学习(或熟悉)多线程使用. Thread 模块除了派生线程外,还提供了基本的同步数据结构,称为锁对象(lo ...

  3. python学习笔记之使用threading模块实现多线程(转)

    综述 Python这门解释性语言也有专门的线程模型,Python虚拟机使用GIL(Global Interpreter Lock,全局解释器锁)来互斥线程对共享资源的访问,但暂时无法利用多处理器的优势 ...

  4. python 多线程编程

    这篇文章写的很棒http://blog.csdn.net/bravezhe/article/details/8585437 使用threading模块实现多线程编程一[综述] Python这门解释性语 ...

  5. day-3 python多线程编程知识点汇总

    python语言以容易入门,适合应用开发,编程简洁,第三方库多等等诸多优点,并吸引广大编程爱好者.但是也存在一个被熟知的性能瓶颈:python解释器引入GIL锁以后,多CPU场景下,也不再是并行方式运 ...

  6. python多线程编程

    Python多线程编程中常用方法: 1.join()方法:如果一个线程或者在函数执行的过程中调用另一个线程,并且希望待其完成操作后才能执行,那么在调用线程的时就可以使用被调线程的join方法join( ...

  7. 关于python多线程编程中join()和setDaemon()的一点儿探究

    关于python多线程编程中join()和setDaemon()的用法,这两天我看网上的资料看得头晕脑涨也没看懂,干脆就做一个实验来看看吧. 首先是编写实验的基础代码,创建一个名为MyThread的  ...

  8. python多线程编程-queue模块和生产者-消费者问题

    摘录python核心编程 本例中演示生产者-消费者模型:商品或服务的生产者生产商品,然后将其放到类似队列的数据结构中.生产商品中的时间是不确定的,同样消费者消费商品的时间也是不确定的. 使用queue ...

  9. 线程和Python—Python多线程编程

    线程和Python 本节主要记录如何在 Python 中使用线程,其中包括全局解释器锁对线程的限制和对应的学习脚本. 全局解释器锁 Python 代码的执行是由 Python 虚拟机(又叫解释器主循环 ...

随机推荐

  1. mongoDB(一)——mongoDB安装部署和常用shell命令

    1.mongoDB简介 mongoDB 是由C++语言编写的,是一种分布式的面向文档存储的开源nosql数据库.nosql是Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统 ...

  2. hashlib的md5计算

    hashlib的md5计算 hashlib概述 涉及加密服务:Cryptographic Services 其中 hashlib是涉及 安全散列 和 消息摘要 ,提供多个不同的加密算法借口,如SHA1 ...

  3. 米特运输——(dfs)

    米特是D星球上一种非常神秘的物质,蕴含着巨大的能量.在以米特为主要能源的D星上,这种米特能源的运输和储 存一直是一个大问题.D星上有N个城市,我们将其顺序编号为1到N,1号城市为首都.这N个城市由N- ...

  4. [Inno Setup] 退出安装程序的两种方式

    1. 完全静默的退出 procedure ExitProcess(exitCode:integer); external 'ExitProcess@kernel32.dll stdcall'; ... ...

  5. java并发Exchanger的使用

    目录 简介 类定义 类继承 构造函数 两个主要方法 具体的例子 结语 简介 Exchanger是java 5引入的并发类,Exchanger顾名思义就是用来做交换的.这里主要是两个线程之间交换持有的对 ...

  6. XEP-0199 XMPP Ping

    原文来自:https://xmpp.org/extensions/xep-0199.html,只翻译了技术方面的内容. 摘要:这个规范定义了一个通过XML流发送应用级别pings的XMPP扩展协议.这 ...

  7. mac OS Apache Tomcat 启动/停止服务

    进入Tomcat下的bin目录 启动Tomcat命令 ./startup.sh Tomcat 默认端口 8080 停止Tomcat服务命令 ./shutdown.sh 执行tomcat ./shutd ...

  8. Spring.getBean()流程和循环依赖的解决

    getBean流程介绍(以单例的Bean流程为准) getBean(beanName) 从BeanFactory中获取Bean的实例对象,真正获取的逻辑由doGetBean实现. doGetBean( ...

  9. caffe学习笔记(1)安装 - Ubuntu 15.04

    官方安装手册 备注:使用系统 - Ubuntu 15.04 64位操作系统(若系统位于虚拟机上,在安装CUDA后,Ubuntu将无法进入图形界面) /************************* ...

  10. 地表最强的MySQL安装一键式安装,信不信你下完我就给你装好!附各种Mysql安装失败的解决办法(什么你安装失败了?快来看这个)

    这里还有数据库相关的优质文章:快戳我,快戳我