1

我有一些我正在尝试加速的代码。我的目标是下载并保存大约一百万个文件。我正在使用请求库来访问内容。我比以往任何时候都更加困惑。大多数 Q/A 建议正确的方法是在任务是 I/O 绑定时使用线程模块,并且由于我正在连接到服务器,等待响应然后将响应写入磁盘我的任务是 I/哦,绑定。

但后来我读到了这样的东西

多个线程可以存在于单个进程中。属于同一进程的线程共享相同的内存区域(可以读取和写入相同的变量,并且可以相互干扰)。

我的代码是这样的 - 在线程之前

def create_list(some_ftp_site):
    # do some stuff to compare the list to
    #  the last list  and return the difference in the two

    return list_to_pull


def download_and save_the_file(some_url):
   thestring = requests.get(some_url).content
   file_ref = open(something)
   fileref.write(the_string)
   fileref.close()


if __name__ == '__main__'
   files_to_get = create_list(some_ftp_site)
   if len(files_to_get) != 0:
       for file_to_get in files_to_get:
           download_and_save(file_to_get)

对我来说,使用其中任何一个都是跳入深渊。因此,如果我对此进行多线程处理,恐怕会发生一些意想不到的事情,例如某个文件的前半部分连接到另一个文件的后半部分。

这种类型的任务是否更适合多处理或多线程。显然,我不知道两个不同的文件部分是否连接在一起,因为它们写入同一个变量

4

4 回答 4

4

两者都可以,但多处理会更安全,也许更容易实现。请记住,特别是对于 Python,全局解释器锁意味着多线程不会从多核中获得太多好处,而多处理则不是问题。

于 2013-08-14T02:30:26.057 回答
2

由于您正在构建一个 IO 绑定应用程序,因此您的大多数应用程序在数据下载时将保持阻塞状态。无论您使用线程还是多处理都是如此。如果你真的想下载一些重要的数据,请使用像 gevent for python 这样的并发框架。还有其他的,但这个框架将允许您在非阻塞状态下进行 IO 调用。换句话说,它就是为这种负载的应用而设计的。

如果你走线程路线,你最终会遇到你可以创建多少线程的墙。

您可以并行运行多少个进程也是如此。

以使用 gevent 为例,您可以创建成千上万个“绿色”线程,因为它们创建起来非常便宜。

http://www.gevent.org

于 2013-08-14T02:38:55.437 回答
2

线程可能会变得混乱,需要通过互斥锁进行变量锁定。您的应用程序似乎适合易于实现的多处理。把你的代码放在一个方法中说:

def download_and_save_the_file(some_url):
    thestring = requests.get(some_url).content
    #Make sure you create unique names
    something = unique_filename(some_url)
    file_ref = open(something)
    fileref.write(the_string)
    fileref.close()  

然后使用多处理和 URL 列表创建一个池,并行下载将按以下方式进行:

from multiprocessing import Pool,cpu_count

p = Pool(cpu_count()-1)
p.map(download_and_save_the_file,files_to_get)
于 2013-08-14T03:14:27.040 回答
1

如果您想加速您的应用程序,那么您将不得不使用多处理,而不是多线程。Python 中的 GIL 意味着线程不像其他语言那样完全独立的执行路径。如果您要运行很多进程,您可能希望考虑在哪个操作系统上托管您的 Python;Windows 中的进程间上下文切换时间并不是特别快。

与任何多进程/多线程应用程序一样,有必要确保每个进程或线程都在做合理的工作量,否则您的应用程序将全部是上下文切换并且实际运行较少......

于 2013-08-14T05:20:35.183 回答