from threading import Thread
import time
import random
# 用于并发执行的函数deftask(num):
time.sleep(random.randint(1,3))print(num)if __name__ =="__main__":# 创建一个用于存放线程的 list# 这种写法如果创建的线程过多, 可能会把性能打死, 所以后续有了线程池的概念
l =[]# 本例中, 索引即使参数, 所以可以直接 append# 如果不是, 可以创建一个参数列表(想法供参考)for i inrange(1,6):
t = Thread(target=task, args=(i,))
l.append(t)# 将线程启动
t.start()# 阻塞到所有线程执行完成for i in l:
i.join()print("end")
类版
需要自己定义 run() 方法
一个类只能起一个线程(不确定)
传参需要在实例化时候传为属性
使用方法和函数版相同, start()+join()
传可以获取返回值(将结果存为 obj 属性)
from threading import Thread
import time
import random
classT(Thread):def__init__(self, num):super().__init__()
self.num = num
self.result =None# 类中方法开并发会找 run 函数defrun(self):
time.sleep(random.randint(1,3))
self.result = self.num **2# 取返回值的方法defget_result(self):return self.result
if __name__ =='__main__':
l =[]for i inrange(5):
t = T(i)
l.append(t)
t.start()for i in l:
i.join()# 输出返回值for i in l:print(i.get_result())print("end")
""" 当主线程回收所有资源之后, 守护线程才会结束 """from threading import Thread
import time
import random
# 用于模拟执行任务deftask():# 模拟执行 5 次for i inrange(5):
time.sleep(random.randint(1,3))print("%s finish"% i)# 作为守护线程defcheck():whileTrue:print("still alive..")
time.sleep(0.5)if __name__ =="__main__":
t = Thread(target=task)
d = Thread(target=check)
d.daemon =True
t.start()
d.start()# 如果需要等待 task 执行完毕在结束主线程, 则要设置 t.join()
t.join()print("end")
高级用法
线程锁 - 基于全局变量操作
from threading import Thread, Lock
import time
deftask():# 区别3: 使用全局变量global n
# 区别4: 基于锁去做处理with mutex:print(n)
time.sleep(0.1)# 模拟计算耗时
n -=1if __name__ =="__main__":# 区别1: 引入一个锁
mutex = Lock()
l =[]# 区别2: 定义 global 变量
n =100for i inrange(n):
t = Thread(target=task)
l.append(t)
t.start()for i in l:
i.join()print("end")
信号量 - semaphore
类似于池, 正在执行的线程为固定数量
完成一个, 再执行一个
from threading import Thread, Semaphore, current_thread
import time, random
sm = Semaphore(5)deftask():with sm:print("%s is laing"% current_thread().getName())
time.sleep(random.randint(1,3))# time.sleep(1)if __name__ =="__main__":for i inrange(20):
t = Thread(target=task)
t.start()