Python3 线程 & GIL 学习笔记
作为Python的初学者,基本上是遇到啥需求,就现去学习,能解决问题就可以。
比如前段时间,做的一个小程序,需要并发处理一些操作,所以就想到了使用线程的概念。
_thread 模块
上网学习了一下
https://docs.python.org/3/library/_thread.html
_thread.start_new_thread(function, args[, kwargs])
这个貌似很简单
因为我的程序把线程启动起来就可以,然后就自己做自己的事情,做完就退出,对全局的东西不需要进行改变,所以也用不到线程锁之类的概念。
我用这个模块实现了我的程序,良好地运行了很长一段时间,完全符合我的要求。
threading 模块
前些天有个新任务,同样需要用到线程。不同的是,我程序中需要用到当前在执行的线程数量,当数量超过我定义的限制,就暂停启动新线程,直到其它线程有结束的,当前线程数量下降。
我想到的方法设置一个全局变量: 线程启动,变量加一; 线程退出,变量减一。
为了防止几个线程同时读写的情况,需要在对变量操作的时候加锁,操作完成释放。
然后我主线程中访问这个变量,判断当前运行中线程的数量
听起来似乎可行,然后我边去学习怎么加锁和释放
然后,我才发现我用_thread被叫做低级( low-level)模块, 而高级(higher-level)模块threading直接提供了
threading.active_count()
https://docs.python.org/3/library/threading.html
既然有了高级模块,咱就别自己造轮子啦。
然后就要去研究一下这个threading 模块咋用啦,结果发现还整出两种使用方法:
方法一:
threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
方法一的方式和_thread.start_new_thread
比较类似。
方法二:
从Thread继承,并重写run()方法
我选择方法二的方式实现我的程序
class myThread (threading.Thread):
在 __init__
中传入要处理的参数
在run
做我要做的处理
在程序中这样启动线程:
thread = myThread(arg_a, arg_b, arg_c)
thread.start()
在程序中使用: threading.active_count()
判断数量
程序运行了几天,最多时候几十个线程再跑,工作状况良好,完全达到预期。
GIL
在了解和学习Python多线程过程中,看到不少对Python多线程的争议。尤其是在多CPU和多核处理器环境下,没法充分利用CPU资源,确切地说,只能可一个CPU霍霍。
究其原因,是因为Python原始解释器CPython中使用了GIL (Global Interpreter Lock,全局解释器锁)来限制线程对共享资源的访问,同一时间只会有一个获得GIL的线程在跑,其他线程则处于等待状态。与其说是多线程,更像是时间片调度,当然了,具体调度方法肯定是更复杂和更科学的。
因为这个GIL的存在,Python多线程,没法真正的并行处理,而是并发处理。对于CPU密集型任务,如果使用多线程,因为GIL的存在导致除了不能利用多核多CPU的优势,反而要浪费时间在线程间切来切去,效率会变得低下。而对于IO密集型任务,因为IO浪费的时间比较多,所以使用多线程是会提升效率的。
看了下我的程序,嗯,还好,都是网络访问的,至少用多线程实现起来很方便,事实也证明很好用。
至于Python下怎么利用多核或者多CPU,据说是使用多进程。
但是我暂时没有这种需要,毕竟,我的原则是,好用就行,折腾啥呀。
另外,关于并发处理,还有可以参考这里:
https://docs.python.org/3/library/asyncio.html
看起来挺高大上的,不明觉厉。
有关GIL可以参考:
https://wiki.python.org/moin/GlobalInterpreterLock
就这样啦,代码啥的就不贴出来充数了。
网上示例一大堆,大家感兴趣的自己去看看好了。
参考资料:
- https://docs.python.org/3/library/_thread.html
- https://docs.python.org/3/library/threading.html
- https://wiki.python.org/moin/GlobalInterpreterLock
- https://docs.python.org/3/library/asyncio.html
- http://www.wellho.net/solutions/python-python-threads-a-first-example.html
- https://www.tutorialspoint.com/python/python_multithreading.htm
- https://stackoverflow.com/questions/2846653/how-to-use-threading-in-python
- http://www.python-course.eu/threads.php
Python的线程好像是有点蛋疼, 如果是CPU密集型的任务, 应该直接进程就好了, 大部分时候是跑满CPU核数, 如果是IO密集型的, 目前大部分都用Event Loop模型了
感谢分享
慢慢摸索中
follow for free coupons
https://steemit.com/@mmansooramin
Great posts can be useful can be an experience. Hopefully be a friend who can help me to like you ..... to dream and hope to be achieved. Like @yooraa need friend support. Best regards.
I do not understand your language,
But I know what python is
Python is the best language. More easy for all programmer especially for new programers
I am an expert in Python
Believe me you will not find strength
It has a great benefit in many areas
Any question you send me and be happy with your friendship
我是Python的专家
相信我,你找不到实力
它在许多领域都有很大的好处
任何问题,你寄给我,并与你的友谊快乐
@oflyhigh Good article, very weighty to be reviewed.
Information is very important for the lovers pemograman.
Hi @oflyhigh! I'm very curious about python. I use visual basic.net for some of my programs but I really don't know what can I do with python programming language. Can I use it in web development as well?
py安装了2个星期了。
启动次数:2
安装时启动1次,阅读完该文启动1次
适合自己的就是最好的
有必要十八般武器样样精通吗?😀
你擅长PHP,就充分发挥PHP的优势好了
我是没啥擅长的,看Python易上手,就拿来学学
Hi, I think your post is very important, but I am unlucky man because I dont understand at all. Could you tell me the core of what you have written on your post? Thanks a lot my feiend. Regard from Aceh.
좋은 게시물. 우리가 인도 할 수 있을까요? 고마워.