多线程对变量同时加的时候 为什么变量会少于加的次数_「原创首发」Python之多线程技术...

本文介绍了Python中线程的基本概念,强调了全局解释器锁GIL的影响,以及在计算密集型和I/O密集型任务中的应用。重点讲解了如何通过互斥锁解决多线程修改共享资源的问题,以及示例展示了加锁前后线程执行结果的变化。
摘要由CSDN通过智能技术生成
04c765d953690c5eb0fa06e8b663933c.png

简意介绍

线程 (Thread) 是操作系统能够进行运算调度的最小单位。它被包含在进程中,是进程中的实际运作单位。一个进程中可以并发多个线程,每条线程并行执行不同的任务。同一进程中的多个线程共享进程中的全部系统资源。

Python 中的多线程因为全局解释器锁 GIL 的原因限制同一时刻只能由一个线程运行,无法发挥多核 CPU 的优势【当然这是在默认解释器 CPython 中的缺陷,在 JPython 中没有 GIL 的问题,以下基于 CPython 解释器】。所以:GIL 并不是 python 的特性,python 也不依赖于 GIL。说了那么多,那么 python 中的多线程是不是没用了?

答案当然不是。这取决于线程执行的场景是什么?是做计算(计算密集型)还是输入输出(I/O 密集型), 针对不同的场景使用不同的方法。多核心 CPU 可以有多个核心并行完成计算,所以多核提升的是计算性能,但每个 CPU 一旦遇到 I/O 阻塞,仍然需要等待,所以多核对 I/O 密集型任务没有太大的提升,多线程适合处理 I/0 密集型程序,如文件读写,web 请求,数据库请求等。

线程特点

d5a866a0816c8358f8f642109070bd4c.png
  1. 线程执行的顺序是不确定的
  2. 主线程【进程】会等待所有子线程结束后才会退出,主线程【进程】结束么子线程必然结束
  3. 线程间共享资源
  4. 修改资源必要时需要加锁,同时避免死锁
  5. 占用的资源比进程少
  6. 线程并不是越多越快
  7. 由于 GIL 的原因,多线程并不是真正的并发,只是交替执行

线程使用

cf9d8ceb9fe554b73be62475b39d6bed.png

以下演示使用多线程对一个变量值进行修改,在循环的次数不多时修改后变量的值是符合预期的,当增加循环次数后,变量最终的值并不符合预期。由此可见:线程之间资源是存在竞争的,修改同一份资源必须加互斥锁,同时需要避免死锁。

# coding=utf-8import threading# 定义一个字段。多线程执行+1操作balance = 0def worker1(): global balance for i in range(1000): balance += 1 print('线程1执行完成,balance='+str(balance))def worker2(): global balance for i in range(1000): balance += 1 print('线程2执行完成,balance='+str(balance))def main(): # 构造线程对象 t1 = threading.Thread(target=worker1) t2 = threading.Thread(target=worker2) # 开始执行 t1.start() t2.start() """ 循环次数为1000时,程序输出: 线程1执行完成,balance=1000 线程2执行完成,balance=2000 循环次数为1000000时,程序输出: 线程1执行完成,balance=1180919 线程2执行完成,balance=1179703 """ if __name__ == '__main__': main()

要想解决以下的问题,需要使用线程的锁对象,只需要对 worker1 和 woker2 方法进行修改。

# 创建一个互斥锁,默认是未锁定状态mutex = threading.Lock()def worker1(): global balance for i in range(1000000): mutex.acquire() balance += 1 mutex.release() print('线程1执行完成,balance=' + str(balance))def worker2(): global balance for i in range(1000000): mutex.acquire() balance += 1 mutex.release() print('线程2执行完成,balance=' + str(balance))"""加了互斥锁之后的输出: 线程1执行完成,balance=1941343 线程2执行完成,balance=2000000"""
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值