| by 鲍 建伟 | No comments

Python的GIL和多进程研究(2)

上一篇简单研究了一下多线程,多进程,接下来研究协程( 微线程 )。先说好嗷,协程是语言内很难理解的东西,我只能尽量说清楚。

一般来说,在我们现代操作系统中,进程只是线程的容器,某个程序打开以后可能有一个或多个进程,每个进程中含有至少含有一个或多个线程。但是说到协程,到底什么是协程?

说到协程,就不得不提异步I/O和同步I/O。我们都知道,CPU的处理速度比网络、磁盘等I/O操作快的多,这样问题就来了,例如执行一段代码,抛去I/O操作CPU只需要一秒来执行,但是网络或者磁盘I/O需要耗时三秒,这样就显著拖慢了整个系统的速度。如果使用同步I/O来操作,这段代码需要至少四秒时间。同步I/O指的是用户进程触发I/O操作时,一直等待或者轮询的去看I/O操作是否完毕。

就因为同步I/O效率有点低,这才有了异步I/O,异步IO是指当进程遇到I/O操作以后就立即返回,继续做自己的事情,而当I/O操作已经完成的时候会得到I/O完成的通知。

所以啊,我们就想,要不然使用多线程或者多进程来并发执行代码试试?

这想法是好的,但是,但是啊!多线程和多进程的可以解决问题,但是系统不能无上限地增加线程。这是因为操作系统切换线程的开销也很大,例如我本科时候的软件工程大作业,当时开了七八个线程,明显能感觉到卡顿了,所以,一旦线程数量过多,CPU的时间就花在线程切换上了,真正运行代码的时间就少了,得不偿失了。

就是因为前面说的这么多原因,才有了协程的大量应用,通俗一点说,协程就是在一个线程内模拟出多线程的执行套路。先写几行代码看一下就明白了:

def test_1():
    print(1)
    print(2)
    print(3)

def test_2():
    print('A')
    print('B')
    print('C')

def main():
    test_1()
    test_2()

if __name__ == '__main__':
    main()

这段代码没有用到协程,就是单线程顺序执行,执行结果我就不上图了,脑运行就可以。 如果上面的代码中,test_1和test_2两个方法分别开两个线程,我们大概就能知道,输出顺序必然不固定对吧, 再看下一段:

妈的我还没研究明白,太鸡儿傻逼了!!!

发表评论