2015-09-30 55 views
0

我有一个python脚本从亚马逊S3服务器下载shell脚本,然后执行它们(每个脚本的大小约为3GB)。下载和执行文件的功能如下所示:多线程python的“文本文件繁忙”错误

import boto3 

def parse_object_key(key): 
    key_parts = key.split(':::') 
    return key_parts[1] 

def process_file(file): 
    client = boto3.client('s3') 
    node = parse_object_key(file) 
    file_path = "/tmp/" + node + "/tmp.sh" 
    os.makedirs(file_path) 
    client.download_file('category', file, file_path) 
    os.chmod(file_path, stat.S_IXUSR) 
    os.system(file_path) 

节点对于每个文件都是唯一的。

我创建了一个for循环来执行此:

s3 = boto3.resource('s3') 
bucket = s3.Bucket('category') 
for object in bucket.objects.page_size(count=50): 
    process_file(object.key, client) 

这完美的作品,但是当我尝试创建一个单独的线程每个文件,我得到错误:

sh: 1: /path/to/file: Text file busy 

脚本与线程看起来像:

s3 = boto3.resource('s3') 
bucket = s3.Bucket('category') 
threads = [] 
for object in bucket.objects.page_size(count=50): 
    t = threading.Thread(target=process_file, args=(object.key, client)) 
    threads.append(t) 
    t.start() 

for t in threads: 
    t.join() 

在所有的线程中,正好一个线程成功,所有oth呃在“文本文件繁忙错误”上失败。有人能帮我弄清楚我做错了什么吗?

+0

什么是'parse_file'? –

+0

而且,就此而言,什么是“下载”? –

+0

它解析file_name以获取url和节点,它们被编码在file_name本身中。下载只是发送一个http请求到远程URL来下载文件并将其保存在fie_path – marrock

回答

0

Boto3不是线程安全的,因此您无法为每次下载重新使用您的S3连接。有关变通方法的详细信息,请参阅here

+0

感谢您的信息!我在每个线程中都做了更改以创建客户端,但我仍然遇到同样的问题。它看起来像文件得到正确下载,但执行步骤失败,“文本文件忙”错误。另外,只有一个线程成功,其他所有线程都会失败。 – marrock

+0

尝试使用'subprocess'而不是'os.system' - https://docs.python.org/3.3/library/subprocess.html#replacing-os-system –

相关问题