线程
一、线程
1、启动方法:
方法一:
步骤1、实例化,t1 = threading.Thread(targe=func, args=())
步骤2、t1.start()
例子:

import threading import time def run(n): print('in the task %s' % n) print('当前线程是\033[31;1m%s\033[0m' % threading.current_thread()) time.sleep(3) t1 = threading.Thread(target=run, args=(1,)) # 注意args参数最后要加逗号 t2 = threading.Thread(target=run, args=(2,)) t1.start() t2.start() print('当前活跃的线程有\033[31;1m%s\033[0m个' % threading.active_count()) print('当前线程是\033[31;1m%s\033[0m' % threading.current_thread())
方法二:
步骤1、定义一个类,继承threading.Thread,并且重写run
步骤2、使用实例中的start()方法
例子:

import threading import time class MyThread(threading.Thread): def __init__(self, n): super(MyThread, self).__init__() self.n = n def run(self): print('现在在线程%s上' % self.n) time.sleep(2) t1 = MyThread(1) t2 = MyThread(2) t1.start() t2.start()
2、统计一个程序所有线程的结束时间:
(1)、原理:使用线程类中的join()方法,此方法阻塞调用线程的执行,直到线程执行完毕。可遍历所有线程的join(),所有线程执行完毕,则开始记录结束时间
(2)、例子:

import threading import time def run(n): print('这是第\033[1;31m%s\033[0m号线程' % n) time.sleep(2) t_list = [] start_time = time.time() for i in range(50): t = threading.Thread(target=run, args=(i,)) t.start() t_list.append(t) for thread in t_list: thread.join() # 此处的作用是阻塞调用线程 print('所有线程的运行时间是:\033[1;31m%s\033[0m秒' % (time.time() - start_time))
二、守护线程
(1)、概念:主线程启动守护线程,主线程等待非守护线程结束就会结束,无视了守护线程。
(2)、例子:

import threading import time def run(n): print('这是第\033[1;31m%s\033[0m号线程' % n) time.sleep(2) start_time = time.time() t_list = [] for i in range(50): t = threading.Thread(target=run ,args=(1,)) t.setDaemon(True) # 设为守护线程 t.start() print('此程序共用时\033[1;31m%s\033[0m秒' % (time.time() - start_time))
三、CPython中的GIL:全局解释锁,Python中的线程可放在多个CPU上,但由于这个锁,这使得同一时间就算有多核cpu,也只能有一个线程工作。
四、互斥锁:
(1)、原因:在2.X版本上,就算有了GIL,如果对线程间的共享数据进行访问,线程1可能由于数据还没计算完,但释放了GIL,这样就允许了线程2对其数据进行计算,并且完成。再回到线程1时就继续在寄存器保存的数据上运算,有可能出现数据不准确。
(2)、如果拿到数据的互斥锁,就可对数据修改;否则就不可以。
(3)使用方法:lock = threading.Lock()
加锁 lock.Acquire()
释放锁:lock.Release()
五、递归锁:
(1)用法:用于互斥锁中锁,避免卡死,只需要使用threading.RLock()
(2)、例子:

import threading lock = threading.RLock() # 多层锁需要实例化RLock() def run1(): global num1 lock.acquire() num1 += 1 lock.release() return num1 def run2(): global num2 lock.acquire() # 第二层锁 num2 += 1 lock.release() return num2 def run3(): lock.acquire() # 第一层锁 print('在函数run1的结果是', run1()) print('在函数run2的结果是', run2()) lock.release() num1, num2 = 0, 0 for i in range(1): t = threading.Thread(target=run3) t.start() while threading.active_count() != 1: print('当前激活的线程个数是:', threading.active_count()) print('线程都执行完毕')
六、信号量(semaphore)
(1)、作用:允许N个线程同时运行,可在实例化时定义。
(2)、例子:

import threading import time semaphore = threading.BoundedSemaphore(5) # 实例化信号量,最多5个线程同时运行 def run(n): semaphore.acquire() print('Thread %s is working...' % n) time.sleep(3) semaphore.release() for i in range(20): t = threading.Thread(target=run, args=(i,)) t.start() while threading.active_count() != 1: pass print('All task done!')
七、threading.event()
1、作用:此类主要用在进程之间的交互,比如说红绿灯,线程红灯亮,则线程车走。。。
2、常用方法:
(1)event.wait():等待设置标志位
(2)event.set():设置标志位
(3)、event.is_set():判断是否设置了标志位
(4)、event.clear():清除标志位
3、例子:

import threading import time event = threading.Event() def light(): count = 0 while True: if count < 10: event.set() # 设为绿灯 print('\033[32;1mThe green light is on\033[0m') elif (count >= 10) and (count <= 15): event.clear() # 去标识,设为红灯 print('\033[31;1mThe red light is on\033[0m') else: count = 0 count += 1 time.sleep(1) def car(name): while True: if event.is_set(): print('%s is running' % name) else: print('%s sees redlight, stop!' % name) event.wait() time.sleep(1) light = threading.Thread(target=light) light.start() car1 = threading.Thread(target= car, args=('Tesla',)) car1.start()
八、队列
1、概念:数据队列是用于存放数据的,与列表不同的是,队列数据取出来后就没有了。并且取数据的顺序主要有三种顺序:先进先出、后进先出、可按优先级取
2、队列类:queue.Queue()、LifoQueue()、PrioprityQueue()
3、共有的方法
(1)、qsize():队列大小
(2)、empty():判断是否为空
(3)、full():判断是否满
(4)、get():按顺序或优先级获取数据
(5)、put():放顺序,注意如果定义的是prioprity队列则可加上优先级、数据组成元组放进去。如put((-3,'Treelight)),数越小优先级越高。
4、例子:生产者和消费者

import threading import queue import time q = queue.Queue(maxsize=10) def producer(): count = 0 while True: count += 1 q.put(count) print('我们餐饮已经准备了第%s个包子' % count) time.sleep(3) def consumer(name): while True: q.get() print('%s已经吃了个包子' % name) time.sleep(1) p = threading.Thread(target=producer) p.start() c = threading.Thread(target=consumer, args=('Treelight',)) c.start()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」