Python 多线程 多进程 全局解释器锁GIL join

Python 代码的执行由Python 虚拟机(也叫解释器主循环)来控制。Python 在设计之初就考虑到要在主循环中,同时只有一个线程在执行,就像单CPU 的系统中运行多个进程那样,内存中可以存放多个程序,但任意时刻,只有一个程序在CPU 中运行。同样地,虽然Python 解释器中可以“运行”多个线程,但在任意时刻,只有一个线程在解释器中运行。
上面是官方的说法,通俗一点讲就是,python程序本身只占用cpu的一个线程,于是python所谓的多线程编程就类似于单CPU情况下的多进程编程。
下面说一下CPU情况下的多进程运行:
多个进程序列通过调度器协调后顺序输入到cpu进行计算,你可以把多任务看成几条溪流,然后调度器是最后的融汇口,进行融汇后流入CPU计算,但是不同的是,单位时间流入CPU的量是一定的,所以把任务分为多进程后进行CPU计算的量和分割前CPU计算量基本一样。
所以对于计算密集型的任务,分为多进程并不会减少计算时间,反而增加了,因为增加了调度时间。
对于IO密集型的任务,多进程是可以的,因为IO密集型对CPU占用相对较少,CPU不会处于满负荷状态,减少了IO的等待时间。
为什么IO可以省时间,计算型密集不可以呢?
我是这么认为的,计算密集型的任务,不管是否分割为多进程,CPU在任务执行期间一直是满负荷的(不管是直接执行这个完整的任务,还是顺序或者调度方式执行多个进程),并不存在空闲资源。
而IO密集型的任务,不管是CPU还是IO,都基本不会使资源满负荷,那么,我们可以把进程分割,让分割出的部分利用好这些资源,所以节省了时间。
下面这个解释也不错:
单cpu多道进程系统有如下特征:
①从宏观上看,几道程序“同时进行”。即他们先后开始了给的运行且均未结束。
②从微观上看,几道程序“交替执行”。对于单cpu进程而言,他们只是轮流占用cpu。
CPU在各进程之间来回切换,,这种快速切换成为多道程序设计。每个进程有自己的控制流程,并且每个都独立地运行。实际上只有一个物理程序计数器,所以在每个程序运行时,他的逻辑计数器被装入设计的程序计数器中。随着时间的推移,当程序结束是,物理程序计数器被保存在内存中该进程的逻辑程序计数器中。所有进程都有所进展,但一个给定的瞬间仅有一个进程真正在运行。
然后我们再来看Python的多线程:
首先确定的是,python在执行过程中每个时刻,其实都只有一个线程在工作。而你所开启的多线程,被编译成可执行代码放到内存中,被任务调度器调度放到这一条“线程流”中,而执行这个调度的,就是 全局解释器锁(GIL)。
介绍几个python多线程相关的关键字:thread和threading、守护线程、join
Python里面有两个线程操作模块thread和threading,用thread创建多线程时,当主线程结束时,所有的线程都会被强制结束掉,没有警告也不会有正常的清除工作。threading 模块能确保重要的子线程退出后进程才退出。
守护线程:如果你的主线程要退出的时候,不用等待那些子线程完成,那就设定这些线程的daemon 属性。即,在线程开始(调用thread.start())之前,调用setDaemon()函数设定线程的daemon 标志(thread.setDaemon(True))就表示这个线程“不重要”。
join:你的python主程序相当于默认存在的一个线程,而当你通过threading新建线程时,这个线程会随着start方法开始跟主程序并行计算,如果不设置join,那么从这个线程start开始,他就与python主程序并行了,join的作用是,当你在python主程序中开启了多个线程并设为join时,这些线程会被附加到主程序上。
#coding=utf-8
import threading
import time
threads=[]
def func(x):
    print 'hello',x
    time.sleep(x)
    print 'I have sleep %d seconds'%x
cur=time.clock()

for i in range(3):
    threads.append(threading.Thread(target=func,args=(i+2,)))
for thread in threads:
    thread.start()
    thread.join()
print 'finish!'
print time.clock()-cur
输出:
hello 2
I have sleep 2 seconds
hello 3
I have sleep 3 seconds
hello 4
I have sleep 4 seconds
finish!
9.0039654844
#coding=utf-8
import threading
import time
threads=[]
def func(x):
    print 'hello',x
    time.sleep(x)
    print 'I have sleep %d seconds'%x

for i in range(3):
    threads.append(threading.Thread(target=func,args=(i+2,)))
for thread in threads:
    thread.start()
    #thread.join()
print 'finish!'
输出:
hello 2
hello 3
hellofinish! 
4
I have sleep 2 seconds
I have sleep 3 seconds
I have sleep 4 seconds
解释一下:
hellofinish! 
4
这里并行执行了print 'hello',4        ;         print 'finish!'
前一条相当于print 'hello',  ,注意语句末尾的逗号和 print ’4‘
在调度时后面一条差到了中间,就打印出了上述结果。

python多进程:
Python提供了multiprocessing处理多进程任务,有兴趣可以看看。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值