threading模块—Python多线程编程

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() 方法,可以让主线程等待所有线程执行完毕。

 1 import threading
 2 from time import sleep, ctime
 3 ?
 4 loops = [4,2]
 5 ?
 6 def loop(nloop, nsec):
 7     print(‘start loop %s at:%s‘ % (nloop, ctime()))
 8     sleep(nsec)
 9     print(‘loop %s done at:%s‘ % (nloop, ctime()))
10 ?
11 def main():
12     print("starting at:%s" % ctime())
13     threads = []
14     nloops = range(len(loops))
15 ?
16     for i in nloops:
17         t = threading.Thread(target=loop, args=(i, loops[i]))
18         threads.append(t)
19 ?
20     for i in nloops:
21         threads[i].start()
22 ?
23     for i in nloops:
24         threads[i].join()
25 ?
26     print(‘all DONE at:%s‘ % ctime())
27 ?
28 ?
29 if __name__ == ‘__main__‘:
30     main()

运行后输出结果:

1 $ mtsleepC.py
2 starting at:Mon Jul 23 12:44:48 2018
3 start loop 0 at:Mon Jul 23 12:44:48 2018
4 start loop 1 at:Mon Jul 23 12:44:48 2018
5 loop 1 done at:Mon Jul 23 12:44:50 2018
6 loop 0 done at:Mon Jul 23 12:44:52 2018
7 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):

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

 1 import threading
 2 from time import sleep, ctime
 3 ?
 4 loops = [4,2]
 5 ?
 6 class ThreadFunc(object):
 7 ?
 8     def __init__(self, func, args, name=‘‘):
 9         self.name = name
10         self.func = func
11         self.args = args
12 ?
13     def __call__(self):
14         self.func(*self.args)
15 ?
16 def loop(nloop, nsec):
17     print(‘start loop %s at:%s‘ % (nloop, ctime()))
18     sleep(nsec)
19     print(‘loop %s done at:%s‘ % (nloop, ctime()))
20 ?
21 def main():
22     print(‘starting at:%s‘ % ctime())
23     threads = []
24     nloops = range(len(loops))
25 ?
26     for i in nloops: # 创建所有线程
27         t = threading.Thread(
28             target=ThreadFunc(loop, (i, loops[i]),loop.__name__)
29             )
30         threads.append(t)
31 ?
32     for i in nloops: # 启动所有线程
33         threads[i].start()
34 ?
35     for i in nloops: # 等待结束
36         threads[i].join()
37 ?
38     print(‘all DONE at:%s‘ % ctime())
39 ?
40 ?
41 if __name__ == ‘__main__‘:
42     main()

运行后的输出结果:

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

子类化的 Thread(mtsleepE.py):

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

 1 import threading
 2 from time import sleep, ctime
 3 ?
 4 loops = [4,2]
 5 ?
 6 class MyThread(threading.Thread):
 7 ?
 8     def __init__(self, func, args, name=‘‘):
 9         threading.Thread.__init__(self)
10         self.name = name
11         self.func = func
12         self.args = args
13 ?
14     def run(self):
15         self.func(*self.args)
16 ?
17 def loop(nloop, nsec):
18     print(‘start loop %s at:%s‘ % (nloop, ctime()))
19     sleep(nsec)
20     print(‘loop %s done at:%s‘ % (nloop, ctime()))
21 ?
22 def main():
23     print(‘starting at:%s‘ % ctime())
24     threads = []
25     nloops = range(len(loops))
26 ?
27     for i in nloops: # 创建所有线程
28         t = MyThread(loop, (i, loops[i]), loop.__name__)
29         threads.append(t)
30 ?
31     for i in nloops: # 启动所有线程
32         threads[i].start()
33 ?
34     for i in nloops: # 等待结束
35         threads[i].join()
36 ?
37     print(‘all DONE at:%s‘ % ctime())
38 ?
39 ?
40 if __name__ == ‘__main__‘:
41     main()

运行后的输出结果:

1 $ mtsleepE.py
2 starting at:Tue Jul 24 09:13:49 2018
3 start loop 0 at:Tue Jul 24 09:13:49 2018
4 start loop 1 at:Tue Jul 24 09:13:49 2018
5 loop 1 done at:Tue Jul 24 09:13:51 2018
6 loop 0 done at:Tue Jul 24 09:13:53 2018
7 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

原文地址:https://www.cnblogs.com/tester-xt/p/9387956.html

时间: 2024-10-07 06:13:41

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

thread模块—Python多线程编程

Thread 模块 *注:在实际使用过程中不建议使用 thread 进行多线程编程,本文档只为学习(或熟悉)多线程使用. Thread 模块除了派生线程外,还提供了基本的同步数据结构,称为锁对象(lock object,也叫原语锁.互斥锁.互斥和二进制信号量). 常用线程函数以及 LockType 锁对象的方法: 函数/方法 描述 thread 模块的函数   start_new_thread(function, args, kwargs=None) 派生一个新的线程,使用给定的 args 和可

Python:使用threading模块实现多线程(转)

分类: python   标签: thread    评论: 暂无评论   阅读:5,420 views 综述 Python这门解释性语言也有专门的线程模型,Python虚拟机使用GIL(Global Interpreter Lock,全局解释器锁)来互斥线程对共享资源的访问,但暂时无法利用多处理器的优势. 在Python中我们主要是通过thread和 threading这两个模块来实现的,其中Python的threading模块是对thread做了一些包装的,可以更加方便的被使用,所以我们使用

python 多线程编程

一)线程基础 1.创建线程: thread模块提供了start_new_thread函数,用以创建线程.start_new_thread函数成功创建后还能够对其进行操作. 其函数原型: start_new_thread(function,atgs[,kwargs]) 其參数含义例如以下: function: 在线程中运行的函数名 args:元组形式的參数列表. kwargs: 可选參数,以字典的形式指定參数 方法一:通过使用thread模块中的函数创建新线程. >>> import th

Python多线程编程

原文 运行几个线程和同时运行几个不同的程序类似,它有以下好处: 一个进程内的多个线程和主线程分享相同的数据空间,比分开不同的过程更容易分享信息或者彼此通信. 线程有时叫做轻量化过程,而且他们不要求更多的内存开支:它们比过程便宜. 一个线程的顺序是:启动,执行和停止.有一个指令指针跟踪线程正在运行的上下文在哪里. 它可以被抢占(中断) 它能暂时被挂起(也叫做休眠),而别的线程在运行--这也叫做yielding(让步). 开始一个新线程: 要生成一个线程,需要调用在thread模块中方法如下: th

day-3 聊聊python多线程编程那些事

python一开始给我的印象是容易入门,适合应用开发,编程简洁,第三方库多等等诸多优点,并吸引我去深入学习.直到学习完多线程编程,在自己环境上验证完这句话:python解释器引入GIL锁以后,多CPU场景下,也不再是并行方式运行,甚至比串行性能更差.不免有些落差,一开始就注定了这门语言迟早是有天花板的,对于一些并行要求高的系统,python可能不再成为首选,甚至是完全不考虑.但是事情也并不是绝对悲观的,我们已经看到有一大批人正在致力优化这个特性,新版本较老版本也有了一定改进,一些核心模块我们也可

python多线程编程----threading模块

1.threading 模块中的内容 - Thread: 一个可执行线程对象 - Lock: 原始的Lock对象 与thread模块中一样 - RLock: 允许单个线程多次请求的Lock - Condition: 线程等待直到条件满足 - Event : 事件发生时,唤醒所有等待进程 - Semaphore:信号量,标识有限资源的个数 - Timer: 定时启动线程 - Barrier: 等待指定的所有的进程都来到 2.daemon threads 守护进程 如果你的主线程准备退出,并且你并不

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

摘录python核心编程 本例中演示生产者-消费者模型:商品或服务的生产者生产商品,然后将其放到类似队列的数据结构中.生产商品中的时间是不确定的,同样消费者消费商品的时间也是不确定的. 使用queue模块(python2.x版本中,叫Queue)来提供线程间通信的机制,从而让线程之间可以分享数据.具体而言,就是创建一个队列,让生产者(线程)在其中放入新的商品,而消费者(线程)消费这些商品. 下表是queue模块的部分属性: 属性 描述 queue模块的类 Queue(maxsize=0) 创建一

python多线程编程(2): 使用互斥锁同步线程

上一节的例子中,每个线程互相独立,相互之间没有任何关系.现在假设这样一个例子:有一个全局的计数num,每个线程获取这个全局的计数,根据num进行一些处理,然后将num加1.很容易写出这样的代码: # encoding: UTF-8import threadingimport time class MyThread(threading.Thread): def run(self): global num time.sleep(1) num = num+1 msg = self.name+' set

Python多线程编程详解

Threading模块从Python 1.5.2 版开始出现,用于增强底层的多线程模块 thread .Threading 模块让操作多线程变得更简单,并且支持程序同时运行多个操作. 注意, Python开发中的多线程最好用于处理有关 I/O 的操作 ,如从网上下载资源或者从本地读取文件或者目录.如果你要做的是 CPU 密集型操作,那么你需要使用 Python 的 multiprocessing 模块.这样做的原因是,Python 有一个全局解释器锁 (GIL),使得所有子线程都必须运行在同一个