这两段代码(关于python GIL)之间的区别是什么?
片段代码1:这两段代码(关于python GIL)之间的区别是什么?,python,gil,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) before = time() thread1 = Thread(target=get_c
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)
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)
要运行代码,结果是5.74065279906323
线程图为:
片段代码2:
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)
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
线程图为:
我认为结果会相似。但最终结果并非如此。为什么?
有人能帮我解释一下吗?
for url in urls:
thread1 = Thread(target=get_content, args=(url,))
thread1.start()
thread1.join()
您的.join
位于for
循环中,因此它将首先启动并加入,然后再移动到下一个线程。在这之后,您应该有第二个循环来加入它们。在第一个代码段中,您实际上是等待每个线程先完成,然后再开始另一个线程。基本上是串行运行,而不是并行运行
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.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)
第一个示例启动一个线程,然后在启动下一个线程之前加入它(等待它完成)。第二个示例启动它们,然后等待它们全部完成。基本上是顺序对并行(或连续对并发)。我从你的问题中删除了gil标记,因为这与gil无关,只是误解了
threadobj.join()
的工作原理。你把它放回去编辑你的标题有什么原因吗?你的答案很有用,非常感谢。你为什么要列出None
s(只是为了把它扔掉)?@jedwards因为在t中只使用[]
。线程中的t的join()不是合法的语法,另一个选项是将它改成两行。我也不想在这里进行优化,只想说明一点。对于线程中的t:t.join()
可以在一行上,而不创建列表。