标签:
Python多线程问题的资料查找与汇总by tsy
声明:
1)本报告由博客园bitpeach撰写,版权所有,免费转载,请注明出处,并请勿作商业用途。
2)若本文档内有侵权文字或图片等内容,请联系作者bitpeach删除相应部分。
3)本文档内容涉及Python的多线程问题,没有介绍多线程的概念,没有介绍多线程的程序模块,只是讨论多线程产生的交织问题,并查找一些材料进行佐证和学习。
4)仅仅作为参考用途,抛砖引玉,不作为证据证明用途,请自行取舍,核实引用。
5)本文的超链接,请不要直接点击,为方便阅读,请选择“在新标签页打开”。
非常抱歉,我不是在博客编辑器编辑的,所以没有时间去调整超链接的窗口参数。
(〇) 说明
本文的排版风格与之前不同,主要的原因本文没有那么正式。最近编写Needleman-Wunsch算法或Smith-Waterman算法的python脚本时,在比对序列过程中,发现样本序列的数量到达一千条时,两两比对的时空复杂度非常高。所以才想使用多线程解决。但是有一些问题随之产生,为了思考和总结多线程的相关知识,所以做一个简单的笔录。本文实际上相当于个备忘录,做一个日志,便于以后对多线程的继续学习和补充。如果也有研究序列比对算法的,欢迎一起讨论。
如果是对序列比对的初学者,我当年是看了博客园的<万仓一黍>的博文《文本比较算法Ⅰ——LD算法》和《文本比较算法Ⅱ——Needleman/Wunsch算法》起步的,前者便于理解序列比对的前身,后者帮助理解全局序列比对。CSDN网友<HUGEHEADHUG>转载博文《动态编程之序列比对:Needleman-Wunsch 算法和Smith-Waterman算法》,对于理解全局序列比对和局部序列比对,虽然转载的该文,我没有找到原文出处,并且该文对于算法的理论介绍较少,主要是代码,但是我觉得还是非常有用。最后我当时还阅读了IBM的技术主题文档《动态编程和基因序列比对》,我一直觉得IBM的这些文档,写得很优秀,不仅仅是这个多序列的,包括其他主题的一些有用的算法,写得非常棒。在分析算法的起源上,引经据典。在算法的文字描述上,排版漂亮,语句通顺,模块思路清晰。在代码实现上,有详有略,代码风格稳健典型。这篇IBM关于多序列比对的文章写得非常赞。以上的几篇文章是我学习多序列比对的一些阅读材料。当初是用C写的,参考的是CSDN博客,<nkliming>网友转载的博文《Needleman-Wunsch Algorithm》,这篇转载的博文中有C++代码,非常值得一读和学习。
后来学习了python,就学习编写基于python的多序列比对算法。但是由于空间复杂度上python毕竟是解释性语言,故担心跟不上c的速度,考虑过几种方法。一是,使用pypy进行加速,与pypy的社区版主讨论过后,发现pypy的部分第三方库支持的不是很好,可能需要从现在开始(2014.12),等上一两年才能开发好,并且vitrualenv目前最近的版本(1.11.6)还不支持默认指定pypy,导致pypy与python在一个操作系统里使用,会很乱的。二是,使用psyco,但是它已经不支持python2.7,psyco支持的最新版本是python2.5。三是,多线程方法,也是本文主要讨论的问题。四是,使用CPython,但是目前还没有时间学,并且我C学的好烂,真的要捂脸。
(一) 多线程的学习参考
(1.1)多线程的简单入门
首先,参看的是博客园的<虫师>的博客原创博文,《python 多线程就这么简单》及其该文的续文,该作者力图使用简单的例子,对多线程有一个初步的认识。我看完之后,觉得挺好的,便于快速使用和快速理解。由于该文将多线程的必要函数给解释了,所以作为快速上手来说,是非常的不错。
如果想再进步一些,阅读该文部分模块没有解释的,例如lock等避免死锁问题想深入探索,可以参考阅读博客园<AstralWind>网友的原创博文《Python线程指南》,这篇博文非常赞,从基本概念到thread(threading)模块的各大大小小的参数都做了基本解释。和<AstralWind>网友文章差不多的,其实还有一篇W3CSCHOOL的文章《Python多线程》,这篇文章也是介绍了模块大大小小的参数。
其次,如果想要实践,做一些小实验。既可以秉承阅读<虫师>的那篇博客,那篇博客作为简单的小实验,再合适不过,通俗易懂。也可以阅读伯乐在线网站的文章《理解Python中的线程》,是从外文文章翻译过来的。还可以阅读ChinaUnix博客网友<那片依然海>所写的原创博文《python中threading模块详解(一)》。博客园的<片片灵感>的原创博文《Python多线程学习》以及他写得另一篇《Python多线程应用》,对实践的内容介绍的比较多,也是不错的选择。
(1.2)多线程的问题产生
接着,我将threading模块运用至我的实际情况。实际情况中,样本为40条序列,每条序列长度都大约为200字符。运算情况为,仅作Needleman运算,将样本两两比对运算,输出两条比对的原序列,输出两条比对后的序列,输出回溯的最长相似序列。单线程情况下近50秒。而使用多线程后,同样情况下,竟然花费近100秒。我当时就产生疑惑,直到百度到一则CSDN帖子《python多线程能提高效率吗?》,几位跟帖的版主或有经验者,指出python有GIL(全局解释器锁)。该帖子所给出的意见无非几条:一是,换语言编写时空复杂度较高的算法部分,如matlab,C/C++,当然了帖子里举例的是Lua,当时查了一下是巴西的一个大学研究小组在1993年开发的,顿时肃然起敬,我朝发展虽然迅猛,什么时候有开发语言的能力啊?就不曾听过中国开发过什么编程语言(请不要说易语言,谢谢。虽然不歧视易语言,但是lua语言作为嵌入式脚本最佳选择,显然是全球推广的,而易语言显然目前没有全球推广,也觉得目前十年内是向全球推广不起来的。)。二是,使用协程或多进程方法。三是,使用解锁或加速插件或其他方法。第一个就不讨论了,第二个我目前还没有整理材料。对于第三个,主要是解锁GIL(个人不太懂,参见博客园<sanlo>网友的博文《在扩展模块中对python的GIL进行解锁》),或者指定多核运行设备的方法,或许可以提高效率。主要汇总的材料如下:
对于GIL的为何使用以及相关概念,有博客园<Tower Joo>(朱涛)网友原创撰写《线程安全及Python中的GIL》。国外文章翻译成中文的讨论GIL的"恐慌"问题,在OSCHINA开源中国社区刊文《Python最难的问题》,也是非常有意思的历史科普。
网上有一篇文章,题为《python并发的痛》,也是谈论这个问题,但是原文出处我找不到了,大多都是转载的,所以超链接是一个转载的链接。该文解释了GIL,解释了当前线程池与GIL产生的矛盾,也介绍了可能并发的其他途径,如多进程+协程的方法来解决。还有一篇新浪博客的技术杂文《Python二三事》,也简要提及了并发的问题。
那么认识GIL除了阅读上面的简介式的文章,如果想深入一些,那可以参看CSDN博客的<I2Cbus>网友原创文章《Python GIL 系列之通过实例认识Python的GIL》,该作者写了几篇关于GIL系列的讨论文章,非常赞!他率先以此文开炮,得出一些结论。并且该作者非常严谨的做了后续补充,纠正了自己之前的错误结论,有益于GIL的演技探索,该作者在此博文给出了一些GIL的其他链接讲解。也就是说这篇博文是刚刚触及GIL的问题,作者意犹未尽,写了《再谈Python的GIL》。
然后< I2Cbus >网友继续撰写了原创技术文章《Python GIL 系列之在Python 2.7改进GIL的一次尝试》,对于python27的提高GIL性能,做了一个讨论的汇总,在该博文中提供了一些材料的链接。其后,该作者使用设置进程运行的CPU来提高Python 的性能,写了《Python GIL 系列之通过设置进程运行的CPU来提高Python程序的性能》及《Python GIL 系列之通过设置进程运行的CPU来提高Python程序的性能(续)》博文,即在线程操作时,为线程指定多核CPU的某一个,避免切换浪费时间,实现和提高Python多核运行的情况(之前说了,单线程下运行比多线程运行还快的问题。该文章或许可以解决,对于我来说,我还没来得及咀嚼吸收,只能从思路和理论上认为是可以解决的,欢迎有人去以此做实验)。
引用网友的评论,觉得评论得挺好的:人类总是不厌其烦的发明简单的语言,同时又不厌其烦的给它增加难以使用的新功能。
本文暂时告一段落,有什么新的发现,会继续补充的。
标签:
原文地址:http://www.cnblogs.com/bitpeach/p/4187079.html