今天看到一篇文章,讲述的是几个提高python性能的项目:传送门 python
在看的过程当中,接触到一个名词,一个从学python开始就一直看到,可是历来都是只知其一;不知其二的名词,内心不开心,必须把它搞明白,对了,这个词就是 GIL。网上搜索了一些资料,粗浅的理解了什么是GIL,本身感受学习的过程比较好,感受略有收获,老规矩,为了巩固知识,本身整片文章出来写一写,其实好多文章已经写的很完善了,因此这篇随笔,只作知识巩固,若有雷同,请各位原创做者原谅,小菜鸟一枚,若是哪里写的有问题,还请各位前辈不吝指正。linux
一句话:解决多线程之间数据完整性和状态同步的最简单方法天然就是加锁。git
首先,GIL的全名,Global Interpreter Lock
,鉴于英文水平,不作名词翻译,以避免误导。大致解释一下,这个锁就是用来为了解决Cpython多线程中线程不安全问题引入的一个全局排它锁,它的做用就是在多线程状况下,保护共享资源,为了避免让多个线程同时操做共享资源,致使不可预期的结果而加上的锁,在一个线程操做共享资源时,其余线程请求该资源,只能等待GIL解锁。这个设置在Cpython刚引入多线程概念的时候就有了,而后后续的各类包和组件开发都不可避免的受到了GIL的影响,因此有人会说,python在多线程处理的时候很慢。python GIL实现方式相似于以下伪代码:github
if __name__ == '__main__': GIL锁开始运做 主线程作操做 主线程完成操做 GIL锁释放资源
因此多线程共同操做共享资源的时候,有一个线程竞得了资源,它就被GIL锁保护起来,其余线程只能是在那里等着,可是这个时候,线程的休眠唤醒,所有会消耗CPU资源,因此嘞,就会慢。安全
看到这个时候,我又发现了一个名词:线程安全。这个名词,也是那种特别熟悉,但就是没法清晰的说出它是啥的概念。查了资料,在这记一下:多线程
线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其余线程不能进行访问直到该线程读取完,其余线程才可以使用。不会出现数据不一致或者数据污染。 线程不安全就是不提供数据访问保护,有可能出现多个线程前后更改数据形成所获得的数据是脏数据。并发
我本身想了一下,大约就是这样,好比整个列表,俩个线程同时在列表中append操做,若是没有锁的保护,在机缘巧合之下,俩个线程同时前后申请了空间且没来得及插入数据,而后这时列表中只会有一个空间,那么在插入过程当中只能有一个数据写入,会形成不可知后果,有可能报错终止,有可能有一个线程操做没成功,那么这个就是线程不安全了,大白话说,只要线程之间没有共享资源,那么就是线程安全的,有共享资源,为了保证线程安全,须要引进锁的机制。app
然后的文章中,有前辈作过实验:框架
顺序执行的单线程(single_thread.py) #! /usr/bin/python from threading import Thread import time def my_counter(): i = 0 for _ in range(100000000): i = i + 1 return True def main(): thread_array = {} start_time = time.time() for tid in range(2): t = Thread(target=my_counter) t.start() t.join() end_time = time.time() print("Total time: {}".format(end_time - start_time)) if __name__ == '__main__': main()
同时执行的两个并发线程(multi_thread.py) #! /usr/bin/python from threading import Thread import time def my_counter(): i = 0 for _ in range(100000000): i = i + 1 return True def main(): thread_array = {} start_time = time.time() for tid in range(2): t = Thread(target=my_counter) t.start() thread_array[tid] = t for i in range(2): thread_array[i].join() end_time = time.time() print("Total time: {}".format(end_time - start_time)) if __name__ == '__main__': main()
最终结果以下:机器学习
以上测试代码和图片引用自:
http://cenalulu.github.io/python/gil-in-python/
过程证实了由于GIL的存在,致使python在使用多线程的时候反而不如顺序执行快。
此处我又温习了一下python线程:
线程的顺序执行仍是多线程并发,取决于join函数的位置。join函数的做用是等待当前线程结束,因此每个线程建立以后,调用start函数,这是在后面跟上该线程的join函数,那么就是顺序执行,若是多个线程先完成建立和start,最后加上join函数,那么就变成了多线程并发。
这就是今天的学习内容,其实全部知识网上都能找到,更想分享的是一种学习的方法,一种自己很不推荐的学习方法,那就是相似于探索性测试的学习,啥不懂就去看啥,有些时候,咱们学习东西确实不能非要究其内在,软件行业的学习自己在非本行人事看来就特别神奇且枯燥,因此最初的学习,咱们须要整个图形界面,让咱们学到的东西有了成就感,若是上来先去研究机器码,那么没几我的愿意学下去,可是无论怎样,既然走上了软件行业的道路,这种探索性,打破砂锅问到底的学习,在个人感受里应该是必经之路,也就是所谓的底层研究。以安卓开发举例,若是作安卓开发的,虽然能写出很漂亮的界面,解决全部的bug,若是不了解安卓系统linux层的知识,在个人眼里,从未把这种研发看作大牛。固然我并不以为不了解linux底层的安卓研发能够解决任何bug
当下的软件行业进入了一个神奇的阶段,我已经听过无数遍的理论,培训机构出来就能赚钱,大学读着没用,在这里不讨论教育体制问题,从我的情感上,我以为大学教育虽然没有教给学生直接找工做的技能,可是给了全部学生一个可以了解基础知识的园地,换而言之,做为行业的一员,总应该有将行业发展起来的觉悟,行业内总体风气,缺少静下心来的沉淀。在大谈敏捷,行为驱动,机器学习的同时,本身须要静下心来回头看看,基础已然不牢,再走下去是否有些危险。是否是学习软件技术,就是为了获取互联网行业那虚高的工资,是否已经局限于第三方框架,一旦框架出现问题,只能打给客服而一筹莫展,是否有过没有作任未尝试就将bug归咎于安卓系统,阿里中间件等等,是否是旧技术还没用明白,为了新技术就能够再也不去研究。
仍是小菜鸟,在此大谈行业发展不免有些放肆,若有不对的地方,还请各位前辈不吝指正