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. Spark SQL源码解析(二)Antlr4解析Sql并生成树

    Spark SQL原理解析前言: Spark SQL源码剖析(一)SQL解析框架Catalyst流程概述 这一次要开始真正介绍Spark解析SQL的流程,首先是从Sql Parse阶段开始,简单点说, ...

  2. vue+element-ui中引入阿里播放器

    1.在public文件下的index.html文件中插入以下代码: <link rel="stylesheet" href="https://g.alicdn.co ...

  3. Qt5 escape spaces in path

    There are two possible ways. You can either use escaped quotes (inserting the string between quotes) ...

  4. 播放声音 (c++) (windows)

    自己看自己看自己看自己看自己看自己看 在<windows.h>中 一:BOOL WINAPI MessageBeep (_in UINT uType ); 播放一个波形文件 (也就是wac ...

  5. 理解分布式一致性:Paxos协议之Multi-Paxos

    理解分布式一致性:Paxos协议之Multi-Paxos Multi-Paxos without failures Multi-Paxos when phase 1 can be skipped Mu ...

  6. 二进制安装MySQL及破解密码

    二进制安装MySQL及破解密码 1.确保系统中有依赖的libaio 软件,如果没有: yum -y install libaio 2.解压二进制MySQL软件包 tar xf mysql-5.7.24 ...

  7. java之 向上转型与向下转型

    向上转型 class father { public void eat(){ System.out.println("father eat()"); } } class son e ...

  8. 【EditPlus】参数设置

    1. 设置javac,java快捷键 工具-参数设置-工具-用户工具 组和工具项-组名,更改组名为“java” 添加工具 javac 菜单文字:javac 命令:安装java的javac.exe的绝对 ...

  9. Redis(三):多机数据库的实现

    复制 在Redis中,用户可以通过SLAVEOF命令或是slaveof选项设置服务器的主从关系,从(SLAVE)服务器会复制主(Master)服务器. 旧版复制功能实现(2.8以前) 旧版复制功能主要 ...

  10. 老男孩Linux运维50期 --于海科--决心书

    1.我叫于海科,来自于甘肃省天水市,之前就读于兰州石化职业技术学院,我是听之前的学长说老男孩教育出来就业不错,我特此来这培训希望出来能够找到一份不错的工作.2.五个月学完,目标薪资是11k.3.达到目 ...