前言:
现时我们对“python threading 暂停”大约比较关心,你们都想要学习一些“python threading 暂停”的相关资讯。那么小编同时在网摘上汇集了一些有关“python threading 暂停””的相关文章,希望各位老铁们能喜欢,大家快快来学习一下吧!上一篇文章有提到为了明确提高 CPU 的使用率,可以采用多线程的方式,以及介绍多线程的概念,对于多线程的概念有兴趣请看我上一篇文章:关于多线程你知道多少呢?
本篇文章将介绍Python的内置库Threading。
Threading常用的方法
将目标指定执行的功能,就是设定的线程设定名称,如果要建立执行参数的参数,可以设定执行的参数,设定格式一定要Tuple(变量,)
threading.Thread(target=function, name="Thread", args=参数)
开始执行线程,开始前面指定线程的名称
<线程>.start()
将主线程暂停,等待指定的线程结束,join前面要放指定的线程名称
<线程>.join()
- 查看当前有多少个线程
threading.active_count()
查看当前使用线程的信息
threading.enumerate()
查看当前在哪个线程中
threading.current_thread()
创建线程实例对象
使用threading.Thread(target=thread_job)建立一个线程对象,并用start开始执行线程。
import threadingdef thread_job(): print("abc")added_thread = threading.Thread(target=thread_job)added_thread.start()等待执行线程结束
使用join()将主线程暂停,等待指定的线程结束,主线程才会结束,下面的代码是为未加join跟加了join的对比。
未加入join()
# 未加入join()import threadingimport time def thread_first_job(x): time.sleep(0.1) print("This is the first thread ", x) def thread_second_job(x): print("This is the second thread ", x)first_thread = threading.Thread(target = thread_first_job, args=("Hi",))second_thread = threading.Thread(target = thread_second_job, args=("Hello",))first_thread.start()second_thread.start()print("all done")# ====== output ======# This is the second thread Hello# all done# This is the first thread Hi加入join()
# 加入 join()import threadingimport time def thread_first_job(x): time.sleep(0.1) print("This is the first thread ", x) def thread_second_job(x): print("This is the second thread ", x)first_thread = threading.Thread(target = thread_first_job, args=("Hi",))second_thread = threading.Thread(target = thread_second_job, args=("Hello",))first_thread.start()second_thread.start()# 使用 join 等待 first_thread 執行完畢first_thread.join()print("all done")# ====== output ======# This is the second thread Hello# This is the first thread Hi# all done
未加 join() 的输出并不会等待 first thread 输出再进行下一步,而加了 join() 后则会等待输出 first thread。
设置守护线程(setDaemon)
若希望在主线程执行完毕后,不管其他的Thread是否已执行完毕,都强制跟主线程一起结束,setDaemon()必须写在start() 之前,预设为 False。
import threadingimport time def thread_first_job(x): time.sleep(5) print("This is the first thread ", x) def thread_second_job(x): print("This is the second thread ", x) first_thread = threading.Thread(target = thread_first_job, args=("Hi",))second_thread = threading.Thread(target = thread_second_job, args=("Hello",))second_thread.setDaemon(True)first_thread.start()second_thread.start()# ---- output --- # This is the second thread Hello# 等待5秒输出 This is the first thread Hi线程的同步机制队列(Queue)
Thread 无法回传值,所以要使用 Queue.put() 将要传回的值存入 Queue,再用 Queue.get() 取出。
import threadingfrom queue import Queue# 将要传回的值存入Queuedef thread_job(data, q): for i in range(len(data)): data[i] = data[i]*2 q.put(data) def multithread(): data = [[1, 2, 3], [4, 5, 6]] q = Queue() all_thread = [] # 使用 multi-thread for i in range(len(data)): thread = threading.Thread(target=thread_job, args=(data[i], q)) thread.start() all_thread.append(thread) # 等待全部 Thread执行完毕 for t in all_thread: t.join() # 使用 q.get() 取出要传回的值 result = [] for _ in range(len(all_thread)): result.append(q.get()) print(result) multithread()# ====== output ======# [[2, 4, 6], [8, 10, 12]]Lock
当同时有几个 Thread 要用到同一个数据时,为了不发生 Race Condition 的现象,需要使用 lock.acquire() 以及 lock.release() 来将其锁定住,不让其他Thread 执行
import threadingdef thread_first_job(): global a, lock lock.acquire() for _ in range(3): a += 1 print("This is the first thread ", a) lock.release()def thread_second_job(): global a, lock lock.acquire() for _ in range(3): a -= 1 print("This is the second thread ", a) lock.release()a = 0lock = threading.Lock()first_thread = threading.Thread(target = thread_first_job)second_thread = threading.Thread(target = thread_second_job)first_thread.start()second_thread.start()first_thread.join()second_thread.join()# ====== output ======# 会先由first_thread执行,执行完才会交給second_thread# This is the first thread 1# This is the first thread 2# This is the first thread 3# This is the second thread 2# This is the second thread 1# This is the second thread 0信号量(Semaphore)
Semaphore 跟 Lock 类似,但 Semaphore 多了计数器的功能,可以允许多个线程同时执行。
import threadingdef thread_first_job(): global a # 取得flag semaphore.acquire() for _ in range(3): a += 1 print("This is the first thread ", a) # 释放flag semaphore.release() def thread_second_job(): global a # 取得falg semaphore.acquire() for _ in range(3): a -= 1 print("This is the second thread ", a) # 释放flag semaphore.release()a = 0# 设定flag计数器为2semaphore = threading.Semaphore(2)first_thread = threading.Thread(target = thread_first_job)second_thread = threading.Thread(target = thread_second_job)first_thread.start()second_thread.start()first_thread.join()second_thread.join()# ====== output ======# first_thread 和 second_thread 会同时执行This is the first thread 1 This is the second thread 0 This is the second thread -1 This is the second thread -2 This is the first thread -1 This is the first thread 0RLock
RLock 跟 Lock 类似,但 RLock 可允许同一个线程重复取得锁定的使用权
使用 acquire 取得 rlock,release 释放rlock
import threadingrlock = threading.RLock()rlock.acquire()rlock.acquire()rlock.release()rlock.release()条件(Condition)
提供比 Lock, RLock更高级的功能: 等待 wait(), 唤醒等待中的线程notify(), 唤醒所有等待中的线程 notifyAll(),也提供了acquire, release方法,threadiong.Condition 在内部维护一个锁对象 (默认是 RLock),可以在创建Condition对象的時候把锁对像作为参数传进去。
import threadingdef thread_first_job(): global a, cond # 取得 lock cond.acquire() print("Acquire the condition lock") # 线程进入等待状态 if a == 0: print("Wait…") cond.wait() # 唤醒线程 print("Notify to wake up…") cond.notify() for _ in range(3): a += 1 print("This is the first thread ", a) # 释放 lock cond.release() def thread_second_job(): global a, cond # 取得 lock cond.acquire() # 唤醒线程 cond.notify() a += 1 # 释放 lock cond.release()a = 0cond = threading.Condition()first_thread = threading.Thread(target = thread_first_job)second_thread = threading.Thread(target = thread_second_job)first_thread.start()second_thread.start()first_thread.join()second_thread.join()# ====== output ======# Acquire the condition lock# Wait...# Notify to wake up...# This is the first thread 2# This is the first thread 3# This is the first thread 4事件(Event)
用于线程间的通信,藉由发送线程设置的信号,若信号为True,其他等待的线程接受到信好后会被唤醒。提供 設置信号 event.set(), 等待信号event.wait(), 清除信号 event.clear() 。
import threadingimport timedef thread_first_job(): global a # 线程进入等待状态 print("Wait…") event.wait() for _ in range(3): a += 1 print("This is the first thread ", a)a = 0# 创建event对象event = threading.Event()first_thread = threading.Thread(target = thread_first_job)first_thread.start()time.sleep(3)# 唤醒处于等待状态的线程print("Wake up the thread…")event.set()first_thread.join()# ====== output ======# Wait...# Wake up the thread...# This is the first thread 1# This is the first thread 2# This is the first thread 3
这些就是使用Python标准库Threading的常用的方法,下一期我将分享我在使用Pandas的一些代码片段。