IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Tâches en parallèle


Sujet :

Shell et commandes GNU

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2015
    Messages : 23
    Par défaut Tâches en parallèle
    Bonsoir,

    Voici mon problème. J'ai un fichier contenant un grand nombre de liens URL (un par ligne). Je sais faire un programme qui, en utilisant cURL, va télécharger chacun de ces fichiers. Je veux en outre stocker le code HTTP de chaque téléchargement (je sais faire aussi) et le stocker dans un fichier. Là aussi, chaque ligne contiendra le code (200 etc.) avec le lien URL associé.

    En fait, j'aimerais faire cela en parallèle. C'est-à-dire lancer plusieurs téléchargements en même temps (bon, je sais que techniquement y en toujours qu'un qui se fait à la fois) pour rendre le traitement plus rapide. Je sais que cela peut se faire en rajoutant & à la fin de chaque appel. On peut faire une boucle qui appelle un certain nombre de fois le script (genre 5 ou 10 par boucle). Le problème se situe plutôt au niveau de la lecture et l'écriture : je ne veux pas que deux processus lisent la même ligne et que deux écrivent sur la même ligne.

    J'ai entendu parlé de la commande parallel mais en lisant la doc, je ne sais pas si elle gère ces problèmes de synchronisation.

    Merci d'avance.

  2. #2
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    salut,

    Citation Envoyé par Svengali48 Voir le message
    bon, je sais que techniquement y en toujours qu'un qui se fait à la fois
    ben... non. si tu parallélises tous les traitements sont réalisés en même temps (on parle du point de vue de l'application, pas du noyau ou du CPU) et la bande passante sera divisée d'autant

    Le problème se situe plutôt au niveau de la lecture et l'écriture : je ne veux pas que deux processus lisent la même ligne et que deux écrivent sur la même ligne.
    je crois que tu fais fausse route, il faut plutôt envisager ça sous cet angle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    while read url < fichier; do
       curl -s "$url" &
    done
    J'ai entendu parlé de la commande parallel mais (...)
    pareil j'en ai entendu parler, je l'ai quasiment jamais utilisé à vrai dire, arrivant toujours à me débattre avec les moyens du bord donc je saurai pas t'aider là dessus

    Edit: typiquement la commande xargs permet de paralléliser l'exécution des commandes elle aussi, un truc du genre serait peut-être à tester :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cat fichier | xargs -n1 -P5 -IURL curl "URL" &   # -P5 = 5 threads

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2015
    Messages : 23
    Par défaut
    Merci pour ta réponse.

    Le problème de ta boucle c'est que si le fichier fait 10 000 lignes, cela va donc lancer 10 000 processus en parallèle ... L'idéal serait de traiter disons 10 processus en parallèle, attendre qu'ils aient fini, puis lancer 10 autres etc. Mais le problème de l'écriture se pose toujours : je ne veux pas que deux processus écrivent sur la même ligne.

    Je vais voir du côté de xargs

  4. #4
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 703
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 703
    Par défaut
    Bonjour,

    L'idéal serait de traiter disons 10 processus en parallèle, attendre qu'ils aient fini, puis lancer 10 autres etc
    il serait préférable de faire une "queue" contenant n (10, 20, tu choisiras) processus maximum.
    ainsi, si dans les n, il y en a un qui met trois plombes, d'autres pourront entrer dans la queue et être traités.

    edit:
    un truc comme ça
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    n=10 #par exemple
    while read line
    do
            until (($(jobs -p | wc -l) < n )); do sleep 1; done
            :do whatever whith line in background &
    don < fichier
    la lecture du fichier sera toujours séquentielle.
    le problème des travaux en arrière-plan, c'est l'écriture dans un fichier.

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2015
    Messages : 23
    Par défaut
    Merci pour l'astuce !

    Pour l'écriture dans un fichier, faut utiliser les "locks" ou bien y a une commande toute faite pour gérer ça ?

  6. #6
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 298
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 298
    Par défaut
    Bonjour

    La documentation de GNU parallel est très bien faite et explicite. Parallel est un xargs amélioré. Lire la section "DIFFERENCES BETWEEN xargs AND GNU Parallel".

  7. #7
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2015
    Messages : 23
    Par défaut
    Bien, voici mon code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    while read url
    do
    	snap_name="$(date +'%s')"
    	while [ -f "./lockfile" ]
    	do	
    		sleep 1
    	done
    	touch "./lockfile"
    	code_status=$(curl -sL -m 10 -w "%{http_code}" "$url" -o ./$snap_name.jpg)
    	rm "./lockfile"
    	if [ "$code_status" = "200" ]
    	then	
    		while [ -f "./lockfile2" ]
    		do	
    			sleep 1
    		done
    		touch "./lockfile2"
    		url2=$(curl -sF "fichier=@./$snap_name.jpg"  http://www.noelshack.com/api.php)
    		echo "$url - $url2" >> ./snapshot.txt
    		rm "./lockfile2"
    	else
    		echo "Aucun snapshot !"
    	fi
    done < ./source
    Je lance ensuite la commande suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    parallel -j10 ::: ./parallele.sh
    Alors, j'obtiens bien des images, le fichier texte se remplit (j'ai bien un résultat par ligne) sauf que parfois, j'obtiens que la moitié des images (enfin, je ne vois que la moitié dans l'icône, quand je l'ouvre c'est genre fichier corrompu), pourtant j'ai bien mis un lock autour du téléchargement ...

  8. #8
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 703
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 703
    Par défaut
    mon intuition me dit que parallel n'est pas correctement utilisé.
    de ce que je comprends, il exécuterait ton script un maximum de 10 fois, mais ton script fait tout d'une traite.
    il me semble que parallel, ici, ne fait rien, en fait.
    ça devrait plutôt resembler à ça, non ?

    tu as observé un gain de temps ?

  9. #9
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2015
    Messages : 23
    Par défaut
    En fait, je me suis gouré, les images ont bien été téléchargées ... Juste que pour certaines d'entre elles, elles n'apparaissaient qu'à moitié sur l'icône de prévisualisation du Bureau alors qu'elles apparaissent entières à la fin du processus.

    Concernant parallel, -j10 signifie maximum 10 processus en même temps, mais oui, pour cet exemple, je ne pense pas voir beaucoup de différences.

  10. #10
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2015
    Messages : 23
    Par défaut
    Autre chose. Apparemment, c'est une astuce courante de donner le "epoch time" comme nom de fichiers quand on en a plein à télécharger. Mais la précision du "epoch time" étant de l'ordre de la seconde, est-il techniquement possible, dans une exécution parallèle, que deux processus stockent exactement le même"eoch time" (supposons donc un processus visant à télécharger un fichier à partir d'une liste d'URL comme dans mon exemple) dans une variable utilisée pour nommer le fichier télécharger ?

  11. #11
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 400
    Par défaut
    Bonjour,

    Plus sur que l'utilisation du epoch time pour une création de fichier temporaire (non garanti sur partition nfs):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ mktemp -p . testdisedorgue_XXXXXXXXXXX
    ./testdisedorgue_vgsKt8lJAo9

Discussions similaires

  1. [Tools] Exécutions des tâches en parallèle
    Par ELKamel dans le forum Spring
    Réponses: 1
    Dernier message: 27/03/2013, 16h56
  2. [SP-2010] Inserer Tache dans flux de travail SP Designer ajoute une tâche en parallèle
    Par Mihnea Niculescu dans le forum SharePoint
    Réponses: 0
    Dernier message: 20/03/2012, 20h56
  3. tâches en parallèle [Timer]
    Par zakarota dans le forum Général Java
    Réponses: 6
    Dernier message: 20/07/2011, 13h09
  4. Executer des tâches en parallèle [Timer]
    Par zakarota dans le forum Général Java
    Réponses: 1
    Dernier message: 06/07/2011, 15h01
  5. Réponses: 2
    Dernier message: 18/06/2009, 10h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo