2015-09-30 1 views
0

J'ai un script python qui télécharge des scripts shell du serveur amazon S3 et les exécute ensuite (chaque script fait environ 3Go). La fonction qui télécharge et exécute le fichier ressemble à ceci:Erreur "fichier texte occupé" sur python multithread

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) 

Le noeud est unique pour chaque fichier.

J'ai créé une boucle pour exécuter ceci:

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

Cela fonctionne parfaitement, mais lorsque je tente de créer un thread séparé pour chaque fichier, je reçois l'erreur:

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

Le script avec le filetage ressemble à:

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() 

De tous les threads, exactement un thread réussir et tous les autres er échoue sur "Erreur de fichier texte occupé". Quelqu'un peut-il m'aider à comprendre ce que je fais de façon incorrecte?

+0

Qu'est-ce que 'parse_file'? –

+0

Et, d'ailleurs, qu'est-ce que 'download'? –

+0

Il analyse le nom_fichier pour obtenir l'URL et le noeud, ils sont codés dans le nom_fichier lui-même. Télécharger juste fait une requête http à l'URL à distance pour télécharger le fichier et l'enregistre à fie_path – marrock

Répondre

0

Boto3 n'est pas compatible avec les threads. Vous ne pouvez donc pas réutiliser votre connexion S3 pour chaque téléchargement. Voir here pour les détails d'une solution de contournement.

+0

Merci pour l'info! J'ai fait les changements pour créer le client dans chaque thread mais je reçois toujours le même problème. Il semble que les fichiers soient téléchargés correctement, mais l'étape d'exécution échoue avec l'erreur "Fichier texte occupé". En outre, un seul thread réussit et tous les autres échouent. – marrock

+0

Essayez d'utiliser 'subprocess' à la place de' os.system' - https://docs.python.org/3.3/library/subprocess.html#replacing-os-system –