GIL锁(Global Interpreter Lock):CPython才会有(是这种解释器的历史遗留问题),Python程序执行前,先获得GIL锁,然后每执行100个指令,解释器就自动释放GIL锁,让别的线程执行。所以,多线程在Python中只能交替执行,同一时间只有一个线程在执行。

Python多线程一般应用于IO密集型程序,不适合用于CPU密集型(以计算为主)程序,因为线程之间的上下文切换也需要时间。如下面例子,多线程不如单线程效率高:

两线程串行:

#coding=utf-8import threading
import timedef computed():i = 0for n in xrange(100000000):i += 1thread_list = []for _ in range(2):time_begin = time.time()thread_list.append(threading.Thread(target=computed))thread_list[_].start()thread_list[_].join()print '两线程串行总运行时间:{}'.format(time.time() - time_begin)# 两线程串行总运行时间:3.20499992371

两线程并行

#coding=utf-8import threading
import timedef computed():i = 0for n in xrange(100000000):i += 1thread_list = []for _ in range(2):time_begin = time.time()thread_list.append(threading.Thread(target=computed))thread_list[_].start()for t in range(2):thread_list[t].join()print '两线程并行总运行时间:{}'.format(time.time() - time_begin)# 两线程并行总运行时间:23.4430000782

线程锁是什么?为什么有了GIL锁还需要线程锁?

在多线程的运算中,可能一个线程执行了100个指令,在切换到了另一个线程的时候,由于它没有计算完毕,而且另一个线程也操作同一个内存对象,这样很容易出现混乱。

说具体点儿,比如一个线程把内存中的a,加1加到一半,切换到另一个线程,另一个线程也是对a加1,且已经加完,并把结果赋给了内存中的a(可以理解为另一个线程的操作不需要这么多指令?),然后第一个线程还是把之前a的值加1,并不是从内存中重新读取再加,所以第一个线程加完之后把结果赋给内存,这样就相当于另一个线程没加上。为了避免这样的问题出现,所以使用线程锁。

#coding=utf-8import threading
import timen, thread_list = 0, []def computed():global nn += 1for _ in xrange(10000):thread_list.append(threading.Thread(target=computed))thread_list[_].start()for t in thread_list:t.join()print n

递归锁

#coding=utf-8import threadingdef run1():print 'grab the first part data'lock.acquire()global numnum += 1lock.release()return numdef run2():print 'grab the second part data'lock.acquire()global num2num2 += 1lock.release()return num2def run3():lock.acquire()res = run1()print '-------between run1 and run2------'res2 = run2()lock.release()print res, res2num, num2 = 0, 0
lock = threading.Lock()
for i in range(10):t = threading.Thread(target=run3)t.start()while threading.active_count() != 1:print threading.active_count()
else:print '---all threads done---'print num, num2

感觉就是锁的嵌套,结果会不停返回“11”,出现混乱。解决方案用递归锁threading.Rlock()。

转载于:https://www.cnblogs.com/allenzhang-920/p/10176895.html

GIL锁,线程锁(互斥锁)和递归锁相关推荐

  1. python中gil锁和线程锁_Python线程——GIL锁、线程锁(互斥锁)、递归锁(RLock)...

    GIL锁 ​ 计算机有4核,代表着同一时间,可以干4个任务.如果单核cpu的话,我启动10个线程,我看上去也是并发的,因为是执行了上下文的切换,让看上去是并发的.但是单核永远肯定时串行的,它肯定是串行 ...

  2. Python之进程+线程+协程(并发与并行、GIL锁、同步锁、死锁、递归锁)

    文章目录 一.并发与并行 二.同步与异步 三.线程锁 1.GIL全局解释器锁 2.同步锁 3.死锁 4.递归锁 在Python中GIL解释器锁.同步锁.死锁.递归锁都是什么?怎么这么多锁,它们都是用来 ...

  3. 嵌入式 自旋锁、互斥锁、读写锁、递归锁

    互斥锁(mutexlock): 最常使用于线程同步的锁:标记用来保证在任一时刻,只能有一个线程访问该对象,同一线程多次加锁操作会造成死锁:临界区和互斥量都可用来实现此锁,通常情况下锁操作失败会将该线程 ...

  4. 可重入锁(递归锁) 互斥锁属性设置

    前言: 上一次刷博客的时候,看到了自旋锁,通过学习Linux内核,对自旋锁有了一定的了解.在学习的过程中看到这么一句话--自旋锁是不可递归的.自旋锁不可递归,难道有可以递归的锁?带着这个问题,我们来看 ...

  5. 自旋锁/互斥锁/读写锁/递归锁的区别与联系

    自旋锁 互斥锁 读写锁 递归锁 互斥锁(mutexlock): 最常使用于线程同步的锁:标记用来保证在任一时刻,只能有一个线程访问该对象,同一线程多次加锁操作会造成死锁:临界区和互斥量都可用来实现此锁 ...

  6. python中的多线程 GIL(全局解释器锁) 死锁与递归锁

    1.什么的是线程 在程序里一个执行路线就叫做线程,线程是程序执行的最小单位 2.多线程的优点 使用线程可以把占据长时间的程序中的任务放到后台去处理. 在处理I/O密集程序的运行速度可能加快(ps:计算 ...

  7. 学习笔记(28):Python网络编程并发编程-死锁与递归锁

    立即学习:https://edu.csdn.net/course/play/24458/296445?utm_source=blogtoedu 1.死锁(Lock()的局限性) 知识点:Lock()只 ...

  8. java线程钥匙_Java多线程并发编程/锁的理解

    一.前言 最近项目遇到多线程并发的情景(并发抢单&恢复库存并行),代码在正常情况下运行没有什么问题,在高并发压测下会出现:库存超发/总库存与sku库存对不上等各种问题. 在运用了 限流/加锁等 ...

  9. python全栈开发第36天------GIL全局解释锁、死锁现象和递归锁、信号量、Event事件、线程...

    一.GIL全局解释锁 定义:本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一个进程必须抢到GIL之后才能使用Cpython解释器来执行自己的代码,无法并行 用途:因为Cpytho ...

最新文章

  1. .NET 数据访问架构指南(转)
  2. error c4996: 'fopen' This function or variable may be unsafe如何解决
  3. AndroidStudio_开发工具的设置_界面设置_字体设置_使用习惯设置_按钮设置等一些设置的介绍---Android原生开发工作笔记71
  4. 【原生JS】web原生文字轮播效果
  5. iPhone is busy: Preparing debugger support for iPhone的解决办法
  6. Pandas快乐学习之上海机动车牌照拍卖
  7. workman 启动的命令行
  8. C# XtraReport学习之三 绑定数据
  9. 民间秘术——镇鬼送神
  10. java 解析der文件_java-如何读取也用bouncycastle在DER中编码的PK...
  11. 粗糙集约简 程序 matlab,粗糙集属性约简matlab程序
  12. 从中国质造到淘宝心选:CBM赋能“数造”新品牌
  13. 简单静态web页面+动画(小案例)
  14. 浅谈带宽,网速和流量之间的关系
  15. 笃行不怠勾勒人才图,望城区人才工作为高质量发展增添强劲动力
  16. CSAPP-Lab05 Cache Lab 深入解析
  17. 神经性脚臭案例整理(一)
  18. 知识付费——移动端音视频加密、防盗播实现方案
  19. 咸鱼硬件—ZTMS开发板固件安装
  20. 嵌入式linux 不识别sata,sata硬盘识别不了的常见问题和解决方法

热门文章

  1. intellij idea rearrange code
  2. JavaScript类数组对象参考
  3. 【Java从0到架构师】项目实战 - 前后端分离、后端校验、Swagger、全局异常处理
  4. 【MyBatis笔记】09-一对多关系建表
  5. 从零开始带你部署springboot项目到ubuntu服务器05
  6. 月薪2W和月薪10W的差别,怎么判断一个产品经理的专业水平高低?
  7. 电信人的数据应用:销售指引系统
  8. flex4.5的DataGrid
  9. java 类变量 赋值_Java 中类变量,实例变量,局部变量的赋值
  10. html中一个页面大概多少px,当屏幕 (浏览器窗口) 小于 768px, 每一列的宽度是 100% -HTML教程_小白教程_css5.net...