threading模块 和 threading.Thread()子类

threading模块定义了以下函数

  • threading.active_count()

Return the number of Thread objects currently alive

  • threading.current_thread()

Return the current Thread object, corresponding to the caller’s thread of control.即主线程返回主线程,子线程返回子线程

  • threading.get_ident()

Return the ‘thread identifier’ of the current thread.

  • threading.enumerate()

Return a list of all Thread objects currently alive. 长度相当于threading.active_count()返回结果

  • threading.main_thread()

Return the main Thread object.子线程返回调用它的主线程对象

例子

import threading,time
def run(n):
    print(f"子线程 {n} 信息",threading.current_thread())
    print(f"子线程 {n} 的id", threading.get_ident())
    print(f"子线程 {n} 的主线程信息",threading.main_thread())
    time.sleep(2)

start_time=time.time()
print("子线程开始前,激活的线程数有",threading.active_count())
print("子线程开始前,线程名为 ", threading.get_ident())
print('-'*40)
#子线程还未开始
t1=threading.Thread(target=run,args=("t1",))
t2=threading.Thread(target=run,args=("t2",))
#子线程已被定义

print("主线程的信息 ",threading.current_thread())

#子线程开始运行
t1.start()
t2.start()

#子线程运行了1s
time.sleep(1)
print('-'*40)

for i in threading.enumerate():
    print("所有线程:",i,i.ident)
print('-'*40)

print("子线程开始后,激活的线程数有",threading.active_count())
print('-'*40)

#子线程并入主线程
t1.join()
t2.join()
print('-'*40)

print("子线程join后,激活的线程数有",threading.active_count())
print("子线程join后,线程名为 ", threading.get_ident())
print("主线程 ",threading.current_thread())
print('-'*40)
print("运行时间 ",time.time()-start_time)
#运行结果
子线程开始前,激活的线程数有 1
子线程开始前,线程名为  20552
----------------------------------------
主线程的信息  <_MainThread(MainThread, started 20552)>
子线程 t1 信息 <Thread(Thread-1, started 19584)>
子线程 t1 的id 19584
子线程 t1 的主线程信息 <_MainThread(MainThread, started 20552)>
子线程 t2 信息 <Thread(Thread-2, started 21604)>
子线程 t2 的id 21604
子线程 t2 的主线程信息 <_MainThread(MainThread, started 20552)>
----------------------------------------
所有线程: <_MainThread(MainThread, started 20552)> 20552
所有线程: <Thread(Thread-1, started 19584)> 19584
所有线程: <Thread(Thread-2, started 21604)> 21604
----------------------------------------
子线程开始后,激活的线程数有 3
----------------------------------------
----------------------------------------
子线程join后,激活的线程数有 1
子线程join后,线程名为  20552
主线程  <_MainThread(MainThread, started 20552)>
----------------------------------------
运行时间  2.001528024673462

threading.Event()

用于主线程控制其他线程的执行,通过event来实现两个或者多个线程之间的交互。
事件主要提供了三个方法:wait()、clear()、set()
event=threading.Event()

全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞(暂停),如果“Flag”值为True,那么event.wait 方法时便不再阻塞。

event.wait(timeout=None):

调用该方法的线程会被阻塞,如果设置了timeout参数,超时后,线程会停止阻塞继续执行;

event.set():

将event的标志设置为True,调用wait方法的所有线程将被唤醒;

event.clear():

将event的标志设置为False,调用wait方法的所有线程将被阻塞;

event.is_set():

判断event的标志是否为True。

import time,threading
thread_stop=threading.Event()#控制循环终止
thread_stop.set()
event=threading.Event()#该事件定义了交通灯的指示情况,True为绿灯,Flase为红灯
def lighter():
    count=0
    event.set()#绿灯
    while thread_stop.is_set():
        if count > 5 and count <10:
            event.clear()#红灯
            print("\033[41;1mred light is on ...\033[0m")
        elif count > 10:
            event.set()#绿灯,重新来过
            print("\033[42;1mgreen light is on ...\033[0m")
            count=0
        else:
            print("\033[42;1mgreen light is on ...\033[0m")
        time.sleep(1)
        count+=1
def car(name):
    while thread_stop.is_set():
        if event.is_set():#绿灯通行
            print("[%s] running ......"%name )
            time.sleep(1)
        else:
            print("[%s]  sees red light.."%name)
            event.wait()#等event==True,即等绿灯亮
            print("[%s] green light is on, start going...")




light = threading.Thread(target=lighter,)
light.start()


car1=threading.Thread(target=car,args=("tesla",))
car1.start()

time.sleep(8)#8秒后停止
thread_stop.clear()
green light is on ...
[tesla] running ......
green light is on ...
[tesla] running ......
green light is on ...
[tesla] running ......
green light is on ...
[tesla] running ......
green light is on ...
[tesla] running ......
green light is on ...
[tesla] running ......
red light is on ...
[tesla]  sees red light..
red light is on ...

threading 获取结果

重写threading.Thread类的run()方法,通过第三方函数get_result获取threading线程返回结果

import time,threading
class ResThread(threading.Thread):

    def __init__(self, func, args=()):
        super(ResThread, self).__init__()
        self.func = func
        self.args = args

    def run(self):
        self.result = self.func(*self.args)

    def get_result(self):
        try:
            return self.result   # 如果子线程不使用join方法,此处可能会报没有self.result的错误
        except Exception:
            return None
def sum(a,b):
    return a+b
a=12
b=323
t1=ResThread(sum,args=(a,b))
t1.start()
a=1323
b=8961
t2=ResThread(sum,args=(a,b))
t2.start()

res1=t1.get_result()
res2=t2.get_result()

print(res1,res2)
335 10284

threading.BoundedSemaphore

最多允许n个线程同时运行

import threading, time


def run(n):
    semaphore.acquire()
    time.sleep(1)
    print("run the thread: %s !" % n)
    semaphore.release()


if __name__ == '__main__':
    start_time = time.time()
    semaphore = threading.BoundedSemaphore(5)  # 最多允许5个线程同时运行
    for i in range(10):
        t = threading.Thread(target=run, args=(i,))
        t.start()

    while threading.active_count() != 1:
        pass
    else:
        print(time.time()-start_time)
        print('----all threads done---')
#Outputs
run the thread: 0 !
run the thread: 1 !
run the thread: 2 !
run the thread: 4 !
run the thread: 3 !
run the thread: 7 !run the thread: 9 !run the thread: 6 !

run the thread: 5 !

run the thread: 8 !
2.0245859622955322
----all threads done---

threading 与 Queue结合

实现数据共享和交换

import threading
import queue,time

q=queue.Queue(maxsize=10)
q.put("骨头 %s"%0 )
def Producer(name):
    count=1
    while not q.empty():
        q.put("骨头 %s"%count)
        print("生产了骨头",count)
        count+=1
        time.sleep(1.2)
    print("没有骨头可以吃了")
def Consumer(name):
    while not q.empty():
        print("[%s] 取到  [%s] 并且吃了它。。。"%(name,q.get()))
        time.sleep(1)


p=threading.Thread(target=Producer,args=('human',))
c=threading.Thread(target=Consumer,args=("dog",))
c1=threading.Thread(target=Consumer,args=("cat",))

p.start()
time.sleep(5)
c.start()
c1.start()
生产了骨头 1
生产了骨头 2
生产了骨头 3
生产了骨头 4
生产了骨头 5
[dog] 取到  [骨头 0] 并且吃了它。。。
[cat] 取到  [骨头 1] 并且吃了它。。。
生产了骨头 6
[dog] 取到  [骨头 2] 并且吃了它。。。
[cat] 取到  [骨头 3] 并且吃了它。。。
[dog] 取到  [骨头 4] 并且吃了它。。。
[cat] 取到  [骨头 5] 并且吃了它。。。
生产了骨头 7
[dog] 取到  [骨头 6] 并且吃了它。。。
[cat] 取到  [骨头 7] 并且吃了它。。。
没有骨头可以吃了

Categories: Python

1 Comment

Python threading.Thread() 线程的终止 – xinzipanghuang.home · 2020年8月6日 at 16:46

[…] threading模块和threading.Thread()子类 […]

Leave a Reply

Your email address will not be published.