python多线程与_thread模块 中介绍了线程的基本概念以及_thread模块的简单示例。然而,_thread模块过于简单,使得我们无法用它来准确地控制线程,本文介绍threading模块,它提供了更强大的多线程管理方案。
threading模块的对象
Thread 表示一个执行线程的对象
Lock 锁原语
RLock 可重入锁对象,使单一线程可以再次获得已持有的锁(递归锁)
Condition 条件变量对象,使得一个线程等待另一个线程满足特定条件
Event 条件变量的通用版本,任意数量的线程等待某个事件的发生,该事件发生后所有线程将被激活
Semaphore 为线程间的共享资源提供了一个计数器,如果没有可用资源时会被阻塞
BoundedSemaphone 与Semaphore相似,不过它不允许超过初始值
Timer 与Thread相似,不过运行前要等待一段时间
Barrier 创建一个”障碍“,必须要达到指定数量的线程才能继续
Thread对象
Thread类表示在单独的控制线程中运行的活动。
主要方法:
threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
None,表示不调用任何东西。
默认情况下,以“Thread-N”的形式构造一个唯一的名字,N是一个小的十进制整数。
()。
{}
//daemon表示是否为守护线程
start() 开始执行线程
run() //定义线程功能
join(timeout=None) //直至启动的线程之前一直挂起,除非给出timeout时间,否则一直阻塞
gerName() //返回线程名
属性:
name //线程名
ident //线程标识符
daemon //是否为守护线程
Threading模块主要函数
- enumerate()返回的列表的长度。
- 它的价值没有直接的意义。
- 它不包括已终止的线程和尚未开始的线程。
- 在正常情况下,主线程是从 Python 解释器中启动的线程。
- 守护线程
如果把一个线程设置为守护线程,就表示这个线程是不重要的,进程退出时不需要等待这些线程执行完成。
执行如下赋值语句可以将一个线程设置为守护线程。thread.daemon=True。
一个新线程会继承父线程的守护标记。
使用锁
锁有两种状态:锁定和未锁定。同时也只支持两种函数,获得锁和释放锁。
lock.acquire() //获取锁
lock.release() //释放锁
当多线程竞争时,允许第一个获得锁的线程进入临界区,执行相应代码。所有之后到达的线程将被阻塞,直到第一个线程执行结束,退出临界区,释放锁。此时,等待的线程可以获得锁并进入临界区,哪个正在等待的线程获取锁是随机的。
1 #!/usr/bin/env python3 2 # coding:utf-8 3 from atexit import register 4 from random import randrange 5 from threading import Thread, current_thread, Lock 6 from time import sleep, ctime 7 8 9 class CleanOutputSet(set): 10 def __str__(self): //改变输出格式 11 return ', '.join(x for x in self) 12 13 14 #lock = Lock() 15 loops = (randrange(2, 5) for x in range(randrange(3, 7))) 16 remaining = CleanOutputSet() 17 18 19 def loop(nsec): 20 myname = current_thread().name //获取当前线程名 21 remaining.add(myname) //添加到集合 22 print('[{0}] Start {1}'.format(ctime(), myname)) 23 sleep(nsec) 24 remaining.remove(myname) 25 print('[{0}] Completed {1} ({2} secs)'.format(ctime(), myname, nsec)) 26 print(' (remaining: {0})'.format(remaining or 'None')) 27 28 29 def main(): 30 for pause in loops: 31 Thread(target=loop, args=(pause,)).start() 32 33 34 @register 35 def _atexit(): 36 print('all DONE at:', ctime()) 37 38 39 if __name__ == '__main__': 40 main()