龙空技术网

Python每日一库之Threading

树哥会编程 356

前言:

现时我们对“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 0
RLock

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的一些代码片段。

标签: #python threading 暂停 #pythonthreading