Skip to main content
 首页 » 编程设计

python之当我在 Python 中使用多线程时无法获得结果

2024年11月01日42Renyi-Fan

我试图用一个 Python 库制作 Instagram scraper。一切顺利,但速度很慢。我试图通过使用多线程来加快速度,但出现了另一个问题。 这是没有多线程的代码,效果很好:

import threading 
import instaloader 
import time 
 
L = instaloader.Instaloader()  
 
def func1(name): 
 
    first = [] 
    posts = instaloader.Profile.from_username(L.context, name).get_posts() 
    posts = list(posts) 
     
    for p in posts[0:5]: 
        first.append(p) 
 
    return first 
 
def func2(name): 
 
    second = [] 
    posts = instaloader.Profile.from_username(L.context, name).get_posts() 
    posts = list(posts) 
 
    for p in posts[5:10]: 
        second.append(p) 
 
    return second 
 
t = time.time() 
 
print(func1('eminem')) 
print(func2('eminem')) 
 
print(time.time()-t)  # this is 47.43 seconds 

但是当我尝试使用多线程时,我发现我的代码执行时间要短得多,但我没有得到结果,它不适用于“return”语句。我需要使用 return 语句,因为这只是代码的一部分,所以我不能使用 print。 这是带线程的代码:

L = instaloader.Instaloader()  
 
def func1(name): 
 
    first = [] 
    posts = instaloader.Profile.from_username(L.context, name).get_posts() 
    posts = list(posts) 
     
    for p in posts[0:5]: 
        first.append(p) 
 
    return first 
 
def func2(name): 
 
    second = [] 
    posts = instaloader.Profile.from_username(L.context, name).get_posts() 
    posts = list(posts) 
 
    for p in posts[5:10]: 
        second.append(p) 
 
    return second 
 
t = time.time() 
 
t1 = threading.Thread(target = func1, args=('eminem',)) 
t2 = threading.Thread(target = func2, args=('eminem',)) 
 
t1.start() 
t2.start() 
 
t1.join() 
t2.join() 
 
print(time.time()-t)  # this is 25.36 seconds 

我做错了什么?

请您参考如下方法:

在您的情况下,最简单的方法是传递具有不同键的共享数据结构,以累积来自不同函数的结果:

而不是使用本地列表 first = [] ; second = [] - 将结果附加到共享结构,如:

def func1(name, results): 
    ... 
    for p in posts[0:5]: 
        results['func1'].append(p) 

func2 函数也是如此。


results = {'func1': [], 'func2': []} 
t1 = threading.Thread(target = func1, args=('eminem', results)) 
t2 = threading.Thread(target = func2, args=('eminem', results)) 
 
t1.start() 
t2.start() 
 
t1.join() 
t2.join() 
 
print(results)  

另一个选项是使用 concurrent.futures.Executor.submit方法。