Python gil奇怪的行为

时间:2017-06-29 08:15:02

标签: python multithreading gil

看看这段代码:

setDT(df1)[order(id, as.Date(visit, "%d %b %Y")), .SD[.N], id]

这是一个读取/写入全局变量的非常基本的函数。 我在同一个函数上运行了2个线程。

我已经读过python由于GIL而在多线程方面效率不高,GIL会自动锁定访问相同资源的函数或方法。 所以,我认为python将首先运行thread1,然后运行thread2,但我可以在控制台输出中看到2个线程并行运行。 所以我不明白gil真正锁定了什么...

由于

1 个答案:

答案 0 :(得分:2)

那是因为sleep系统调用释放CPU(甚至"从解释器退出"一段时间)

执行time.sleep(0.2)时,系统(而不是Python)暂停当前线程一段时间,允许另一个线程工作。

请注意,您可以插入以监视线程的print语句或threading.current_thread()也会(简要地)生成系统,因此线程可以因此而切换(请记住Schrodinger's cat)。 真正的测试将是:

from threading import Thread
import time

cpt = 0

def myfunction():
    global cpt
    for x in range(10):
        cpt += 1
        time.sleep(0.2)
    print(cpt)

thread1 = Thread(target=myfunction)
thread2 = Thread(target=myfunction)
thread1.start()
thread2.start()

你来了

20
20

这意味着每个线程都会依次增加计数器。

现在评论time.sleep()声明,您将获得:

10
20

表示第一个线程占用所有增加,结束,让第二个线程增加10个计数。没有系统调用(甚至print)确保GIL完全正常工作。

GIL不会导致性能问题,它只是阻止2个线程并行运行。如果你需要真正并行运行python代码,你必须使用multiprocessing模块(包括所有约束,酸洗,分叉......)