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

最新文章

  1. pysproto bug修复
  2. double保持精度,防止小数点后数字的丢失的小方法
  3. 二十、【.Net开源】EFW框架核心类库之WebService服务
  4. 你连Bug都抓不住,还谈什么参与感?
  5. Java for LeetCode 036 Valid Sudoku
  6. 安装mssql2008和启动时出现的问题及解决办法
  7. Ubuntu将软件(Sublime Text 2为例)锁定到启动器
  8. laravel框架——路由
  9. (转)Maven实战(二)构建简单Maven项目
  10. Android之ListView的快速滑动模式:fastScrollEnabled以及滑块的自定义
  11. 28 自定义View流式布局
  12. Servlet之监听器(Listener)
  13. 8张图让你一步步看清 async/await 和 promise 的执行顺序
  14. 用Windows Media Service打造的流媒体点播
  15. python & MySQLdb(two)
  16. n2n的编译和运行、配置
  17. python---windows下安装和使用memcache
  18. [NOIP2005普及组]采药(01背包)
  19. Sprint8
  20. 谈谈Linux内核驱动的coding style【转】

热门文章

  1. 详解 字符串—— String、StringBuffer 与 StringBuilder
  2. CVE-2019-0193 Apache solr velocity模块漏洞
  3. 新增记录txt文档
  4. wget下载整个网站---比较实用--比如抓取Smarty的document
  5. mac、window版编辑器 webstorm 2016... 永久破解方法。
  6. 使用pthread进行编程
  7. 微信小程序 POST传值跳坑
  8. thinkphp5 input坑
  9. 实现QQ内打开链接跳转至浏览器
  10. Bogon