如何对整个函数进行线程化?

时间:2019-06-25 20:23:13

标签: python python-3.x python-multithreading

我的目标是重新编写一个旧的代码库,使其具有一个可以同时下载url的函数,并且我希望避免在该函数当前已编码到程序中的任何地方编写threading.Thread(target = func_that_downloads_things).start()

如果我能保留大部分读取func_that_downloads_things()的旧代码库(并将线程功能直接工作到执行下载的功能中),那就太好了。

此代码同时下载所有4个网址:

import requests, threading, time

def func_that_downloads_things():
    request_method = 'GET'
    request_url = 'http://olympus.realpython.org/dice'
    r = requests.request(method=request_method, url=request_url, timeout=4)
    print(r.text + '... took ' + str(round(time.time() - thread_start_time, 4)) + " seconds to download... and threading.active_count() is at " + str(threading.active_count()))

#take the start time
thread_start_time = time.time()

#download 4 websites
threading.Thread(target = func_that_downloads_things).start()
threading.Thread(target = func_that_downloads_things).start()
threading.Thread(target = func_that_downloads_things).start()
threading.Thread(target = func_that_downloads_things).start()

#take the end time
thread_end_time = time.time()

#tell the world how long it took to start the threads and get to this point
print('took '+ str(round(thread_end_time - thread_start_time, 6)) + ' seconds to initiate all the downloads')

print("threading.active_count() is at " + str(threading.active_count()))

该代码不提供:

import requests, threading, time

def func_that_downloads_things(url):
    def dl(url):
        request_method = 'GET'
        request_url = url
        r = requests.request(method=request_method, url=request_url, timeout=4)
        print(r.text + '... took ' + str(round(time.time() - thread_start_time, 4)) + " seconds to download... and threading.active_count() is at " + str(threading.active_count()))
    threading.Thread(target = dl(url)).start()

#take the start time
thread_start_time = time.time()

#download 4 websites
func_that_downloads_things('http://olympus.realpython.org/dice')
func_that_downloads_things('http://olympus.realpython.org/dice')
func_that_downloads_things('http://olympus.realpython.org/dice')
func_that_downloads_things('http://olympus.realpython.org/dice')

#take the end time
thread_end_time = time.time()

#tell the world how long it took to start the threads and get to this point
print('took '+ str(round(thread_end_time - thread_start_time, 6)) + ' seconds to initiate all the downloads')

print("threading.active_count() is at " + str(threading.active_count()))

为什么?

1 个答案:

答案 0 :(得分:3)

替换

threading.Thread(target = dl(url)).start()

作者

threading.Thread(target = dl, args=(url,)).start()

您的代码在创建线程之前首先运行dl(url),因为以这种方式编写始终是对函数(或构造函数)的调用。

第二个代码仅将未调用的函数对象与参数一起交给线程对象。然后,在新创建的线程中使用给定的参数调用该函数。