实用:pyhon中异常的产生对多线程中影响

这篇博客探讨了Python中异常如何影响多线程的运行情况,通过具体案例展示了异常处理在多线程环境中的行为和处理策略,对于理解和优化多线程程序具有实际指导意义。
import threading
import time

def foo1():
    try:
        1/0

    finally:
        print('foo1 fin')

def foo2():
    time.sleep(4)
    try:
        foo1()
    finally:
        print('foo2 fin')
    while True:
        time.sleep(1)

t = threading.Thread(target=foo2)
t.start()#子线程

while True:#主线程
    time.sleep(1)
    print('-------------')
    if t.is_alive():
        print('alive')
    else:
        print('dead')

运行结果:

-------------
alive
-------------
alive
-------------
alive
foo1 fin
foo2 fin
-------------
alive
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.5/threading.py", line 862, in run
    self._target(*self._args, **self._kwargs)
  File "/home/yzx/PycharmProjects/python/t32.py", line 14, in foo2
    foo1()
  File "/home/yzx/PycharmProjects/python/t32.py", line 6, in foo1
    1/0
ZeroDivisionError: division by zero

-------------
dead
-------------
dead
-------------
dead
-------------
dead
-------------
dead#一直持续打印dead,所以子进程产生异常中断了子进程,但并不影响主线程的继续执行

案例二:

import threading
import time

def foo1():
    try:
        1/0

    finally:
        print('foo1 fin')

def foo2():
    time.sleep(4)
    try:
        foo1()
    finally:
        print('foo2 fin')
    while True:
        time.sleep(1)

# t = threading.Thread(target=foo2)
# t.start()

while True:
    time.sleep(1)
    print('-------------')
    foo2()
    # if t.is_alive():
    #     print('alive')
    # else:
    #     print('dead')

运行结果:

-------------
foo1 fin
Traceback (most recent call last):
foo2 fin
  File "/home/yzx/PycharmProjects/python/t32.py", line 26, in <module>
    foo2()
  File "/home/yzx/PycharmProjects/python/t32.py", line 14, in foo2
    foo1()
  File "/home/yzx/PycharmProjects/python/t32.py", line 6, in foo1
    1/0
ZeroDivisionError: division by zero

Process finished with exit code 1  #主线程产生了小异常中断了主线程的执行,在生产环境中意味着当前程序主线程崩溃,为避免此类生产事故发生把一些不重要的代码放进子线程单独跑!
### Python中的GIL及其对多线程编程的影响 Python的全局解释器锁(Global Interpreter Lock, GIL)是一个互斥锁,用于保护访问Python对象,防止多个原生线程同时执行Python字节码[^1]。这意味着即使是在多核处理器上运行,任何给定时间也只有一个线程在执行Python代码。 对于I/O密集型应用而言,尽管存在GIL,Python多线程仍然能带来性能提升,因为当一个线程等待I/O操作完成时,另一个线程可以继续执行其他任务。但对于CPU密集型的应用来说,由于GIL的存在使得同一时刻仅有一个线程被执行,这可能会成为瓶颈,从而限制了通过增加更多线程来获得更好的计算资源利用率的可能性[^2]。 为了克服由GIL带来的局限性,在某些情况下可以通过以下几种方式提高基于多线程架构下的应用程序效率: - **采用多进程模式**:利用`multiprocessing`库创建新的操作系统级别的进程而不是线程,这样每个子进程中都有独立的内存空间和自己的GIL实例,进而实现了真正意义上的并行处理能力。 - **编写C扩展或者使用Cython**:针对那些特别耗时的操作部分改用更高效的低级语言如C/C++重写,并将其编译成共享库供Python调用;也可以考虑借助于Cython这样的工具将特定函数转换为优化后的机器指令集版本。 - **引入异步编程范式**:运用诸如`asyncio`, `trio`之类的框架开发事件驱动风格的服务端软件设计,它们允许在一个单独的工作单元里高效管理大量轻量级的任务协作而无需频繁切换上下文环境。 ### 提高Python多线程程序性能的具体方法 除了上述提到的技术手段外,还有一些具体的实践技巧可以帮助改善受制于GIL情况下的多线程表现: #### 使用多进程替代多线程 Python提供了`multiprocessing`模块作为解决因GIL造成的单一线程串行化问题的有效途径之一。该模块不仅支持跨平台兼容性的子进程启动机制,还包含了丰富的同步原语集合(信号量、条件变量等),以便开发者构建复杂的分布式系统结构[^3]。 ```python from multiprocessing import Process def worker(): """worker function""" print('Worker') if __name__ == '__main__': jobs = [] for i in range(5): p = Process(target=worker) jobs.append(p) p.start() ``` #### 利用第三方库减轻负担 一些专门面向高性能运算场景打造的数据科学/工程类库已经内置了许多底层加速特性,比如NumPy数组操作会自动释放GIL让位给外部BLAS/LAPACK实现; Pandas则会在适当时候转交给经过高度优化过的Fortran或C源码片段去完成核心算法逻辑. #### 设计合理的任务分配策略 合理规划各个工作单位之间的负载均衡程度同样重要——尽量使各条流水线上保持相近水平的工作强度分布,避免出现某几个固定位置长期处于忙碌状态而其余大部分闲置浪费的局面发生。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值