有两段代码(关于python GIL)有什么区别?

时间:2018-07-02 11:55:34

标签: python gil

片段代码1

before = time()
urls = ['https://google.com'] * 5
for url in urls:
    thread1 = Thread(target=get_content, args=(url,))
    thread1.start()
    thread1.join()
after = time()
print(after - before)

要运行代码,结果为5.740652799606323
线程图为: image link

片段代码2

before = time()
thread1 = Thread(target=get_content, args=('https://google.com',))
thread2 = Thread(target=get_content, args=('https://google.com',))
thread3 = Thread(target=get_content, args=('https://google.com',))
thread4 = Thread(target=get_content, args=('https://google.com',))
thread5 = Thread(target=get_content, args=('https://google.com',))
thread1.start()
thread2.start()
thread3.start()
thread4.start()
thread5.start()
thread1.join()
thread2.join()
thread3.join()
thread4.join()
thread5.join()
after = time()
print(after - before)

要运行代码,结果为:1.102950096130371
线程图为: image link

我认为结果将会相似。但是最终结果不是。为什么?
有人可以帮我解释一下吗?

3 个答案:

答案 0 :(得分:2)

在第一个代码段中,您实际上要等每个线程先完成 first ,然后再启动另一个线程。您基本上是串行运行它,而不是并行运行。

for url in urls:
    thread1 = Thread(target=get_content, args=(url,))
    thread1.start()
    thread1.join()

使用线程时,您可能想做的是将每个线程保存在一个容器(列表)中,启动所有线程,然后等待所有线程完成。

ths = []
for url in urls:
    thread1 = Thread(target=get_content, args=(url,))
    thread1.start()
    ths.append(thread1)

for t in ths:
    t.join()

此代码实际上只是循环执行第二个片段所要做的事情。

答案 1 :(得分:1)

thread1.join()等待线程完成。您在循环中添加了它,这意味着直到第一个请求完成后,循环才会进入下一个迭代。

从本质上讲,您已经“杀死”了多线程概念,并迫使程序一次执行一个请求。

一种更改方法是做这样的事情:

before = time()
urls = ['https://google.com'] * 5
threads = []
for url in urls:
    thread1 = Thread(target=get_content, args=(url,))
    thread1.start()
    threads.append(thread1)
[t.join() for t in threads]
after = time()
print(after - before)

答案 2 :(得分:0)

for url in urls:
    thread1 = Thread(target=get_content, args=(url,))
    thread1.start()
    thread1.join()

您的.joinfor循环内,因此它将首先启动并加入,然后移至下一个线程。在那之后,您应该有第二个循环来代替它们。