网站首页 > 文章精选 正文
先熟悉下相关概念
多线程是并发编程的一种方式,多线程在 CPU 密集型任务中无法充分利用多核性能,但在 I/O 操作(如文件读写、网络请求)等待期间,线程会释放 GIL,此时其他线程可以运行。GIL是Python 解释器的全局锁,同一时刻只能有一个线程执行 Python 字节码。我们先来看看如何创建和启用的
先要导入相关模块,threading
通过线程实例来模拟下,代码如下:
import threading
import time
def test(name):
print(f"线程 {name} 开始")
time.sleep(2) # 模拟 I/O 操作
print(f"线程 {name} 结束")
# 创建线程
thread1 = threading.Thread(target=test, args=("1",))#线程实例1
thread2 = threading.Thread(target=test, args=("2",))#线程实例2
# 启动线程
thread1.start()
thread2.start()
# 等待线程结束
thread1.join()
thread2.join()
print("所有开启的线程都已经结束")
运行下看看
实际使用中,多线程操作共享资源时可能引发竞态条件,我们如何保证线程安全呢?
就需要买一把锁,和我们生活中一样,锁下控制,保障安全进行使用
如何用锁呢,通过使用模块 threading中的Lock()方法,然后在运行中去使用产生它
lock = threading.Lock()
我们多线程和锁(Lock)来安全地对共享变量 counter 进行累加操作。两个线程各自执行 100,000 次累加,预期下我们的最终结果为 200,000,代码如下
import threading
counter = 0
lock = threading.Lock()#锁的对象
def test_lock():
global counter #明确下 全局
for _ in range(100000):
with lock: # 自动加锁/释放,保证独占counter,退出后允许其他线程使用
counter += 1#假如没有锁的话,会竞争,切换时可以能被线程打断,导致少加
#在with内,确保累计
threads = []
for _ in range(2):#创建2个
t = threading.Thread(target=test_lock)
threads.append(t)
t.start()
for t in threads:
t.join()
print(f"最后输出counter是: {counter}") # 正确结果应为 200000
看下运行情况
但是频繁锁也不好,会影响一些性能,可以考虑线程容器,比如队列。
队列使用安全传递,代码如下:
总的来说,多线程使用场景不少,通过用线程,我们可以提示软件的响应时间、吞吐量等。但是我们要避免死锁。采用锁、队列等一些方法来保护共享资源,合理使用线程,避免过度创建,导致产生问题。
就这了,更深入的自己去深挖吧。
猜你喜欢
- 2025-05-25 Java线程池配置与调优:让程序跑得更快更稳
- 2025-05-25 Java线程:从青铜到王者的必修课(附实战代码)
- 2025-05-25 Linux系统编程—线程属性
- 2025-05-25 RT-Thread快速入门-线程管理(上)
- 2025-05-25 5分钟学会C/C++多线程编程进程和线程
- 2025-05-25 终于明白:有了线程,为什么还要有协程?
- 2025-05-25 多线程编程精要:从用户线程到线程池的效能进化论
- 2025-05-25 多线程——线程池的正确打开方式
- 2025-05-25 Spring Boot3 中多线程技术的使用指南
- 2025-05-25 线程的状态有哪些?它是如何工作的?
- 最近发表
-
- 面试中常被问到的Hash表,你了解吗
- JAVA面试考点:一文搞懂一致性Hash的原理和实现
- 一次性搞清楚equals和hashCode(hashcode() 与equals()区别,简单说明)
- HashMap.Key的故事:Key为什么出现Hash碰撞及冲突呢?
- hash冲突的几种解决方案对比(hash冲突的解决方式)
- 游戏王LN 无头骑士(无头骑士cv)
- Linux ln、unlink命令用法(linux link命令详解)
- n和l分不清矫正发音方法,这三步就够了
- golang引用私有gitlab项目代码(golang引入当前包下的文件)
- Instamic:录音领域中的 GoPro,让你想录就录,随心所欲
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)