首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python线程和GIL

Python线程和GIL
EN

Stack Overflow用户
提问于 2015-04-18 00:14:45
回答 1查看 423关注 0票数 5

假设我有一个线程和程序的主要部分。因为GIL,一个线程应该一次工作,对吧(而不是同时)?但是,如果其中一个线程是无限循环(或者两者都是)呢?

这两个进程会并行运行吗?

代码语言:javascript
复制
def test():
    while True:
       print "hello"

def test2():
    while True:
       print "hi"

def start_thread():
    try: 
        thread.start_new_thread( test2,() )
    except:
        print "Error: Unable to start thread"
start_thread()
test()
EN

回答 1

Stack Overflow用户

发布于 2015-04-18 00:23:34

它们将并行运行,但实际上不是并行的。操作系统将频繁地在两个线程之间来回切换,以便它们都能够完成自己的工作。这就是“并发”的含义;一个线程不需要等待另一个线程完成,它就可以开始工作。但由于GIL,它们实际上永远不会同时运行,因为它们都是在不同的内核上并行运行的。每个线程都会运行一段时间,在其他线程运行时暂停,然后再次开始运行,然后暂停,依此类推。

如果只运行示例代码,这一点很容易理解。下面是我机器上的输出:

代码语言:javascript
复制
hello
hi
hello
hi
hello
hi
hello
hi
hello
hi
hello
hi
hello
hi
hello
hi
hello
hi

显然,两个线程都在运行。每个线程的运行速度都比程序中只有一个线程运行时慢。

考虑这个例子,其中每个线程计算fibonacci序列:

代码语言:javascript
复制
import thread
import time


def fib(n):
    if n <= 1:
        return n

    return fib(n-1) + fib(n-2)

def test():
    while True:
       start = time.time()
       out = fib(32)
       print "hello %s: %s" % (out, str(time.time() - start))

def test2():
    while True:
       out = fib(20)

def start_thread():
    try: 
        thread.start_new_thread( test2,() )
    except:
        print "Error: Unable to start thread"
#start_thread()
test()

在只运行test的情况下(所以没有第二个线程),我得到以下输出:

代码语言:javascript
复制
hello 2178309: 0.953778982162
hello 2178309: 0.954975128174
hello 2178309: 0.95578789711
hello 2178309: 0.949182033539

如果我也在后台启动test2,我会得到如下结果:

代码语言:javascript
复制
hello 2178309: 4.07990288734
hello 2178309: 4.08523893356
hello 2178309: 2.51651597023
hello 2178309: 2.13291287422
hello 2178309: 2.19885015488

正如你所看到的,性能会受到很大的影响。

注意,如果其中一个线程正在做一些释放GIL的事情-比如阻塞I/O,或者调用释放GIL的C库-你不会看到这种性能下降,因为在这种情况下,两个线程实际上都可以并行运行。这在上面的例子中并不适用,因为两个线程都没有做释放GIL的工作。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29704445

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档