常用用法
t.is_alive()
Python中线程会在一个单独的系统级别线程中执行(比如一个POSIX线程或者一个Windows线程)
这些线程将由操作系统来全权管理。线程一旦启动,将独立执行直到目标函数返回。可以通过查询
一个线程对象的状态,看它是否还在执行t.is_alive()
t.join()
可以把一个线程加入到当前线程,并等待它终止
Python解释器在所有线程都终止后才继续执行代码剩余的部分
daemon
对于需要长时间运行的线程或者需要一直运行的后台任务,可以用后台线程(也称为守护线程)
例:
t=Thread(target=func,args(1,),daemon=True)
t.start()
后台线程无法等待,这些线程会在主线程终止时自动销毁
小结:
后台线程无法等待,不过,这些线程会在主线程终止时自动销毁。你无法结束一个线程,无法给它发送信
号,无法调整它的调度,也无法执行其他高级操作。如果需要这些特性,你需要自己添加。比如说,
如果你需要终止线程,那么这个线程必须通过编程在某个特定点轮询来退出
如果线程执行一些像I/O这样的阻塞操作,那么通过轮询来终止线程将使得线程之间的协调变得非常棘手。
比如,如果一个线程一直阻塞在一个I/O操作上,它就永远无法返回,也就无法检查自己是否已经被结束了。
要正确处理这些问题,需要利用超时循环来小心操作线程。
线程间通信
queue
一个线程向另外一个线程发送数据最安全的方式应该就是queue库中的队列
先看一下使用例子,这里是一个简单的生产者和消费者模型:
from queue import Queuefrom threading import Threadimport randomimport time_sentinel = object()def producer(out_q): n = 10 while n: time.sleep(1) data = random.randint(0, 10) out_q.put(data) print("生产者生产了数据{0}".format(data)) n -= 1 out_q.put(_sentinel)def consumer(in_q): while True: data = in_q.get() print("消费者消费了{0}".format(data)) if data is _sentinel: in_q.put(_sentinel) breakq = Queue()t1 = Thread(target=consumer, args=(q,))t2 = Thread(target=producer, args=(q,))t1.start()t2.start()
上述代码中设置了一个特殊值_sentinel用于当获取到这个值的时候终止执行
关于queue的功能有个需要注意的地方:
Queue对象虽然已经包含了必要的锁,主要有q.put和q.get
而q.size(),q.full(),q.empty()等方法不是线程安全的
使用队列进行线程通信是一个单向、不确定的过程。通常情况下,是没有办法知道接收数据的线程是什么时候接收到的数据并开始工作的。但是队列提供了一些基本的特性:q.task_done()和q.join()
如果一个线程需要在另外一个线程处理完特定的数据任务后立即得到通知,可以把要发送的数据和一个Event放到一起使用
新闻热点
疑难解答