我的问题如下:我的应用程序需要使用python中的Boto库同时将多个文件上传到S3。我已经找到了2个解决方案,但我不确定每个解决方案的含义。一些注意事项:
解决方案,最快,然后最慢:
1)使用from threading import Thread
“手动”创建线程。这在aprox中执行。 0.02秒。
from boto.s3.connection import S3Connection
from threading import Thread
import time
filenames = ['1.json', '2.json', '3.json', '4.json', '5.json', '6.json', '7.json', '8.json', '9.json', '10.json']
def upload(myfile):
conn = S3Connection(aws_access_key_id=AWS_KEY, aws_secret_access_key=AWS_SECRET)
bucket = conn.get_bucket("parallel_upload_tests")
key = bucket.new_key(myfile).set_contents_from_string('some content')
return myfile
for fname in filenames:
t = Thread(target = upload, args=(fname,)).start()
2)使用ThreadPool
模块中的multiprocessing
。这需要aprox。执行0.3秒(几乎慢10倍)
from boto.s3.connection import S3Connection
from multiprocessing.pool import ThreadPool
import time
filenames = ['1.json', '2.json', '3.json', '4.json', '5.json', '6.json', '7.json', '8.json', '9.json', '10.json']
def upload(myfile):
conn = S3Connection(aws_access_key_id=AWS_KEY, aws_secret_access_key=AWS_SECRET)
bucket = conn.get_bucket("parallel_upload_tests")
key = bucket.new_key(myfile).set_contents_from_string('some content')
return myfile
pool = ThreadPool(processes=16)
pool.map(upload, filenames)
非常感谢。
编辑:我也刚刚意识到multiprocessing
有一个pool
(可能会创建新进程)和ThreadPool
(可能会创建线程工作者)。我有点困惑。
答案 0 :(得分:2)
Python使用OS线程。虽然你没有为CPU绑定任务获得任何东西,但线程对于你的IO绑定任务来说很好。 GIL, the Global Interpreter Lock,将发布IO用于发布。
multiprocessing
模块专为CPU绑定任务而设计。在您的情况下,它启动16个新进程。这需要时间。通常情况下,创建更多的工作者/进程比拥有CPU更有意义。我的经验法则是number_of_workers = number_of_cpus - 1
。此外,它使用pickle进行通信以进行进程之间的通信。如果您需要连续多次上传,您可能希望尝试启动多个工作程序并使其保持活动状态并一遍又一遍地重复使用它们。只要您为每次上传做了明显的计算,这可能证明启动新进程的开销是合理的。您需要根据您的情况对此进行分析。
第三种选择是异步。例如,您可以使用Twisted。然后,您需要重新构建代码,因为您需要使用回调。