python多任务编程补充_GIL_互斥锁

张开发
2026/6/9 18:54:38 15 分钟阅读
python多任务编程补充_GIL_互斥锁
当前使用的python解释器为cpython类型包含了一个GIL全局解释器锁GIL的存在目的是为了限制在同一时刻中只有一个线程在执行python字节码防止资源竞争。简单讲一下过程python代码被编译为字节码放到内存中只要程序没有终止字节码就一直存在当函数被调用时字节码就会被执行此时他会获得GIL在该函数机器码被执行的期间其他的字节码无法被执行也就是说python的多线程本质上仍然是并发而非并行IO操作I/Osleep网络文件时释放GIL并行等待一句话代码的执行无法并行但是IO等待可以并行CPython 中Python 层面的计算是并发交替的IO 操作可以真正并行等待。然后是互斥锁多线程中涉及的线程安全问题我们通过以下案例来展示全局变量g_sumfunc1和funct2循环对g_sum进行1操作最终的结果输出应该是g_sum2*10**6但实际输出却小于这个值基于python3.8的输出结果1操作的过程有三步骤读取内存中g_sum的值进行g_sum1操作将g_sum写回内存中但是因为没有限制对g_sum的访问假设func1在写回前func2又读取了g_sum的值这一1操作将会‘作废’因为func2拿到的并不是func1修改好的g_sum而是func1修改前的g_sumimport threading g_sum 0 def func1(lock): global g_sum for i in range(10**6): g_sum 1 print(g_sum) def func2(lock): global g_sum for i in range(10 ** 6): g_sum 1 print(g_sum) if __name__ __main__: task1 threading.Thread(targetfunc1,args(lock,)) task2 threading.Thread(targetfunc2,args(lock,)) task1.start() task2.start()为了避免上述情况发生引入互斥锁互斥锁是线程中的概念目的是帮助当前线程获取执行权同时给这个执行权上锁当满足某个条件时才释放权限因此我们使用互斥锁来保证当其中一个线程对g_sum进行操作时其余的线程只能等待不能操作g_sum知道当前轮次对g_sum的操作完成了再释放互斥锁有下一个获得互斥锁的线程进行操作。几个重要操作import threading #导入库 lock threading.Lock() #创建一个互斥锁 lock.acquire() #请求获取互斥锁 lock.release() #释放互斥锁import threading g_sum 0 def func1(lock): global g_sum for i in range(10**6): lock.acquire()#请求锁 g_sum 1 lock.release() # 释放锁 print(g_sum) def func2(lock): global g_sum for i in range(10 ** 6): lock.acquire()#请求锁 g_sum 1 lock.release() # 释放锁 print(g_sum) if __name__ __main__: lock threading.Lock()#创建互斥锁 task1 threading.Thread(targetfunc1,args(lock,)) task2 threading.Thread(targetfunc2,args(lock,)) task1.start() task2.start()通过引入互斥锁保证1操作不会重叠执行最终输出结果为2*10**6额外补充内容获取进程的idthreading.current_thread().native_id #由os操作系统分配的线程id 该线程结束后也不会被复用 threading.current_thread().ident #由python解释器分配的线程id 该线程结束后可能被复用

更多文章