GIL锁,线程锁(互斥锁)和递归锁
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锁,线程锁(互斥锁)和递归锁相关推荐
- python中gil锁和线程锁_Python线程——GIL锁、线程锁(互斥锁)、递归锁(RLock)...
GIL锁 计算机有4核,代表着同一时间,可以干4个任务.如果单核cpu的话,我启动10个线程,我看上去也是并发的,因为是执行了上下文的切换,让看上去是并发的.但是单核永远肯定时串行的,它肯定是串行 ...
- Python之进程+线程+协程(并发与并行、GIL锁、同步锁、死锁、递归锁)
文章目录 一.并发与并行 二.同步与异步 三.线程锁 1.GIL全局解释器锁 2.同步锁 3.死锁 4.递归锁 在Python中GIL解释器锁.同步锁.死锁.递归锁都是什么?怎么这么多锁,它们都是用来 ...
- 嵌入式 自旋锁、互斥锁、读写锁、递归锁
互斥锁(mutexlock): 最常使用于线程同步的锁:标记用来保证在任一时刻,只能有一个线程访问该对象,同一线程多次加锁操作会造成死锁:临界区和互斥量都可用来实现此锁,通常情况下锁操作失败会将该线程 ...
- 可重入锁(递归锁) 互斥锁属性设置
前言: 上一次刷博客的时候,看到了自旋锁,通过学习Linux内核,对自旋锁有了一定的了解.在学习的过程中看到这么一句话--自旋锁是不可递归的.自旋锁不可递归,难道有可以递归的锁?带着这个问题,我们来看 ...
- 自旋锁/互斥锁/读写锁/递归锁的区别与联系
自旋锁 互斥锁 读写锁 递归锁 互斥锁(mutexlock): 最常使用于线程同步的锁:标记用来保证在任一时刻,只能有一个线程访问该对象,同一线程多次加锁操作会造成死锁:临界区和互斥量都可用来实现此锁 ...
- python中的多线程 GIL(全局解释器锁) 死锁与递归锁
1.什么的是线程 在程序里一个执行路线就叫做线程,线程是程序执行的最小单位 2.多线程的优点 使用线程可以把占据长时间的程序中的任务放到后台去处理. 在处理I/O密集程序的运行速度可能加快(ps:计算 ...
- 学习笔记(28):Python网络编程并发编程-死锁与递归锁
立即学习:https://edu.csdn.net/course/play/24458/296445?utm_source=blogtoedu 1.死锁(Lock()的局限性) 知识点:Lock()只 ...
- java线程钥匙_Java多线程并发编程/锁的理解
一.前言 最近项目遇到多线程并发的情景(并发抢单&恢复库存并行),代码在正常情况下运行没有什么问题,在高并发压测下会出现:库存超发/总库存与sku库存对不上等各种问题. 在运用了 限流/加锁等 ...
- python全栈开发第36天------GIL全局解释锁、死锁现象和递归锁、信号量、Event事件、线程...
一.GIL全局解释锁 定义:本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一个进程必须抢到GIL之后才能使用Cpython解释器来执行自己的代码,无法并行 用途:因为Cpytho ...
最新文章
- .NET 数据访问架构指南(转)
- error c4996: 'fopen' This function or variable may be unsafe如何解决
- AndroidStudio_开发工具的设置_界面设置_字体设置_使用习惯设置_按钮设置等一些设置的介绍---Android原生开发工作笔记71
- 【原生JS】web原生文字轮播效果
- iPhone is busy: Preparing debugger support for iPhone的解决办法
- Pandas快乐学习之上海机动车牌照拍卖
- workman 启动的命令行
- C# XtraReport学习之三 绑定数据
- 民间秘术——镇鬼送神
- java 解析der文件_java-如何读取也用bouncycastle在DER中编码的PK...
- 粗糙集约简 程序 matlab,粗糙集属性约简matlab程序
- 从中国质造到淘宝心选:CBM赋能“数造”新品牌
- 简单静态web页面+动画(小案例)
- 浅谈带宽,网速和流量之间的关系
- 笃行不怠勾勒人才图,望城区人才工作为高质量发展增添强劲动力
- CSAPP-Lab05 Cache Lab 深入解析
- 神经性脚臭案例整理(一)
- 知识付费——移动端音视频加密、防盗播实现方案
- 咸鱼硬件—ZTMS开发板固件安装
- 嵌入式linux 不识别sata,sata硬盘识别不了的常见问题和解决方法
热门文章
- intellij idea rearrange code
- JavaScript类数组对象参考
- 【Java从0到架构师】项目实战 - 前后端分离、后端校验、Swagger、全局异常处理
- 【MyBatis笔记】09-一对多关系建表
- 从零开始带你部署springboot项目到ubuntu服务器05
- 月薪2W和月薪10W的差别,怎么判断一个产品经理的专业水平高低?
- 电信人的数据应用:销售指引系统
- flex4.5的DataGrid
- java 类变量 赋值_Java 中类变量,实例变量,局部变量的赋值
- html中一个页面大概多少px,当屏幕 (浏览器窗口) 小于 768px, 每一列的宽度是 100% -HTML教程_小白教程_css5.net...