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

Python Discussion :

Processus asynchrone et processus parallèle [Python 3.X]


Sujet :

Python

  1. #1
    Membre actif Avatar de FadeToBlack
    Homme Profil pro
    ...
    Inscrit en
    Août 2010
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : ...
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Août 2010
    Messages : 314
    Points : 204
    Points
    204
    Par défaut Processus asynchrone et processus parallèle
    Bonjour à tous,

    Je crée ce post parce que je n'arrive pas à comprendre, sans doute une notion de base, la différence entre l'asynchrone et le parallèlisme.

    Pour le moment, je n'ai pas de problème de code à rédiger, je verrais cela plus tard. Il s'agit des concepts que je n'arrive pas à comprendre.

    Mais pour une question de compréhension, je vais essayer de prendre un exemple précis. Exemple idiot mais je n'ai rien trouver de mieux.

    Disons que j'ai un répertoire "Rep_A" qui contient des sous-répertoires, et des fichiers. Disons plusieurs dizaines de milliers de fichiers.

    Un répertoire "Rep_B" qui possède une arborescence différentes avec aussi plusieurs dizaines de milliers de fichiers.

    Problématique :
    Je veux faire la liste de mes fichiers dans "Rep_A" et vérifier s'ils existent dans "Rep_B", et vérifier qu'ils sont identiques.
    Si oui, écrire dans un fichier Same.txt, le nom et chemin du fichier identique (dans Rep_A)
    Si non, écrire dans un fichier different.txt le nom et chemin du fichier dans (Rep_A).



    Je suppose que prendre le premier fichier de Rep_A, faire la recherche dans Rep_B, comparer les deux fichiers, puis écrire dans un des deux txt, puis faire de même pour le second fichier etc..... va prendre beaucoup de temps.

    Je me suis dis qu'il serait peut-être intéressant de lancer plusieurs tâche de recherche et de comparaison en parallèle. Histoire de profiter de toute ma Ram et de mes multicore.


    Comment appréhender ce problème avec du parallèlisme ou de l'asynchrone. Quelles sont les différences entre les deux ?.


    Je vous remercie de votre aide.

    Boonne journée à tous.

  2. #2
    Membre averti Avatar de zancrows
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2016
    Messages : 158
    Points : 355
    Points
    355
    Par défaut
    Bonjour,

    si tu n'es pas déjà tombé dessus tu devrais faire un tour ici --> http://sametmax.com/la-difference-en...t-concurrente/
    il explique de manière simple la programmation asynchrone, parallèle et concurrente.

  3. #3
    Membre actif Avatar de FadeToBlack
    Homme Profil pro
    ...
    Inscrit en
    Août 2010
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : ...
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Août 2010
    Messages : 314
    Points : 204
    Points
    204
    Par défaut
    merci Zancrows,

    j'avais effectivement vu cet article. Mais c'est à la lecture de ce post (un peu vieux me semble-t-il car avant la 3.5) que me viennent mes troubles.

    Comment déterminer quels orientations prendre dans mon cas d'étude . C'est à ce niveau là que je ne comprends pas. C'est aussi peut être que je n'ai pas compris l'article......

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 480
    Points : 9 277
    Points
    9 277
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je suis loin d'être un spécialiste de ces questions, mais par expérience, on peut lancer plusieurs tâches qui s'exécuteront en même temps dans des cœurs différents du microprocesseur. Pour faire ça, on peut utiliser le module "multiprocessing" ou "concurrent.futures".

    Mais si l'un des processus a besoin des résultats de l'autre, c'est ton cas, ça se gâte un peu puisqu'il faut assurer une synchronisation entre les 2! On peut le faire avec l'accès (contrôlé!) à des variables communes que chaque processus peut lire et modifier. J'utilise couramment pour ça de variables "multiprocessing.Queue()".

    Pire encore, si en permanence pour chaque fichier de Rep_A, tu as besoin de connaître tous les fichiers de Rep_B pour chercher, je ne vois aucun intérêt à vouloir faire des opérations en même temps!

    Il ne te reste alors qu'à travailler l'algorithme pour que la réponse se fasse dans un temps acceptable... Par exemple, une fois les fichiers de Rep_B trouvés, on peut construire un dictionnaire avec comme clés les noms de fichiers et comme valeur la liste des adresses-disque (le répertoire avec son chemin) dans lesquelles on trouve chacun des noms. Une fois ce dictionnaire créé, la recherche est très rapide puisque les clés sont "hashées". Il ne restera plus qu'à vérifier que ces fichiers portant le même nom ont bien le même contenu.

    Ça, c'est pour le principe, mais ça dépend aussi de ton contexte. Par exemple si tu dois faire d'autres choses avant avec ton programme, tu peux lancer la recherche des fichiers de Rep_B dans un processus différent afin d'être prêt plus rapidement pour la future recherche Rep_A <=> Rep_B. Bref, il faut réfléchir un peu à l'utilisation réelle de ton programme pour choisir la bonne solution.

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 344
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 344
    Points : 36 865
    Points
    36 865
    Par défaut
    Salut,

    Citation Envoyé par tyrtamos Voir le message
    Mais si l'un des processus a besoin des résultats de l'autre, c'est ton cas, ça se gâte un peu puisqu'il faut assurer une synchronisation entre les 2! On peut le faire avec l'accès (contrôlé!) à des variables communes que chaque processus peut lire et modifier. J'utilise couramment pour ça de variables "multiprocessing.Queue()".
    Techniquement, c'est du pipelining qui est une variante du parallélisme.
    Mais pour votre code, çà serait mieux d'avoir une version qui fonctionne avant d'essayer de l'accélérer en parallélisant tout ou partie des traitements.
    note: un version qui fonctionne, c'est coder les opérations de bases. "paralléliser", ce sera ajouter du code pour que ces traitements communiquent via multiprocessing ou threads.

    - W

  6. #6
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 480
    Points : 9 277
    Points
    9 277
    Billets dans le blog
    6
    Par défaut
    Bonjour

    Citation Envoyé par wiztricks Voir le message
    Techniquement, c'est du pipelining qui est une variante du parallélisme.
    Merci pour l'info! J'ai prudemment évité de rentrer dans la typologie des méthodes...

    Citation Envoyé par tyrtamos Voir le message
    Par exemple, une fois les fichiers de Rep_B trouvés, on peut construire un dictionnaire avec comme clés les noms de fichiers et comme valeur la liste des adresses-disque (le répertoire avec son chemin) dans lesquelles on trouve chacun des noms. Une fois ce dictionnaire créé, la recherche est très rapide puisque les clés sont "hashées". Il ne restera plus qu'à vérifier que ces fichiers portant le même nom ont bien le même contenu.
    Je complète ma réponse précédente.

    Voilà une petite fonction qui va analyser le répertoire Rep_B pour retourner un dictionnaire des noms de fichiers avec la liste des répertoires contenant chacun de ces fichiers:

    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
    def trouvefichiersdico(repertoire, dicofics={}):
        """Trouve tous les fichiers du répertoire donné et de son arborescence.
           Retourne un dictionnaire dont les clés sont les noms de fichier
           et les valeurs sont la liste des répertoires contenant chaque fichier.
           erreurs est la liste des messages d'erreur rencontrés.
        """
        erreurs = []
        try:
            for entree in os.scandir(repertoire):
                if entree.is_file(follow_symlinks=False):
                    if entree.name in dicofics:
                        dicofics[entree.name].append(repertoire)
                    else:
                        dicofics[entree.name] = [repertoire]    
                elif entree.is_dir(follow_symlinks=False):
                    dicofics, errs = trouvefichiersdico(entree.path, dicofics)
                    erreurs += errs
        except Exception as msgerr:
            erreurs.append(msgerr)
        return dicofics, erreurs
    Si je prends pour exemple mon répertoire Python de 1,10 Go qui contient 40365 Fichiers et 4118 Dossiers (j'ai beaucoup de modules externes d'installés):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    repertoire = r"E:\Programmes\Python35"
    dicofics, erreurs, nbreps = trouvefichiersdico(repertoire)
    Il ressort que s'il y a 40365 fichiers, il n'y a que 26781 noms de fichiers différents dans les 4118 sous-répertoires.
    A l'affichage du dictionnaire, on va trouver par exemple, pour le nom de fichier "image.py":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    images.py
    ===> E:\Programmes\Python35\Lib\site-packages\docutils\parsers\rst\directives
    ===> E:\Programmes\Python35\Lib\site-packages\OpenGL\GL
    ===> E:\Programmes\Python35\Lib\site-packages\OpenGL
    ===> E:\Programmes\Python35\Lib\site-packages\sphinx\transforms\post_transforms
    ===> E:\Programmes\Python35\Lib\site-packages\sphinx\util
    ===> E:\Programmes\Python35\Lib\site-packages\wx\lib\editor
    ===> E:\Programmes\Python35\Lib\site-packages\wx\lib\pdfviewer
    ===> E:\Programmes\Python35\Lib\site-packages\wx\py
    La réponse à la question <le fichier "image.py" de Rep_A existe-t-il dans Rep_B> sera facile:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    fichier = "images.py"
    print("Recherche du fichier", fichier)
    if fichier in dicofics:
        print("Trouvé dans le(s) répertoire(s):)
        for rep in dicofics[fichier]:
            print("===>", rep)
    else:
        print("Non trouvé")
    L'exécution est assez rapide: pour ce répertoire de plus de 40000 fichiers, cela prend quelques petites secondes au plus (0.5 seconde chez moi)

    Pour l'exploration du répertoire Rep_A, on peut proposer une autre fonction qui, elle, va retourner la liste complète de tous les fichiers du répertoire avec leur chemin:

    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
    def trouvefichiers(repertoire, listefics=[], nbreps=0):
        """Trouve tous les fichiers du répertoire donné et de son arborescence.
           Retourne une liste de ces fichiers avec leur chemin
           erreurs est la liste des messages d'erreur rencontrés.
        """
        erreurs = []
        nbreps += 1
        try:
            for entree in os.scandir(repertoire):
                if entree.is_file(follow_symlinks=False):
                    listefics.append(entree.path)
                elif entree.is_dir(follow_symlinks=False):
                    listefics, errs, nbreps = trouvefichiers(entree.path, listefics, nbreps)
                    erreurs += errs
        except Exception as msgerr:
            erreurs.append(msgerr)
        return listefics, erreurs, nbreps
    Il suffira donc pour résoudre le problème posé (si je l'ai bien compris):

    - de calculer le dictionnaire des fichiers de Rep_B
    - de calculer la liste des fichiers de Rep_A
    - de prendre dans une boucle tous les fichiers de la liste (Rep_A) et de comparer avec le dictionnaire (Rep_B)
    - au cas ou le nom de fichier se retrouve bien dans les 2 arborescences, et pour tous les sous-répertoires concernés, on peut comparer les tailles (os.path.getsize), les dates de dernière modif (os.path.getmtime), voire faire une comparaison binaire entre les 2 contenus.

    On peut trouver utile de faire chacun des 2 calculs (concernant Rep_A et Rep_B) dans 2 processus simultanés (multiprocessing.Process) dans 2 cœurs différents du microprocesseur, mais il faudra attendre que les 2 soient terminés pour commencer les recherches.

  7. #7
    Membre actif Avatar de FadeToBlack
    Homme Profil pro
    ...
    Inscrit en
    Août 2010
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : ...
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Août 2010
    Messages : 314
    Points : 204
    Points
    204
    Par défaut
    Bonjour à tous et merci de vos échanges.

    Histoire de faire simple, je me suis imaginé une procédure plus simple :

    J'ai créé un répertoire Rep_A simple avec x fichiers. J'en ai calculé le md5. J'ai ensuite créé un fichier texte resume.md5 qui contient le hash et le nom du fichier hashé.

    J'ai ensuite copié ce répertoire, renommé Rep_B, et fais quelques modifications sur certains fichiers, histoire d'être sûr que le md5 sera modifié.

    Je ne fais que calculer le Md5 des fichiers de Rep_B et les compare aux résultats contenu dans le fichier resume.md5
    Si il y pas d'erreurs, j'incrémente une variable "correcte". En cas de différences entre deux md5, j'incrémente une variable "incorrecte" et j'écris le nom du fichier incorrecte dans un fichier error.txt.


    Voici, une premier version sans multiprocessing :
    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    import hashlib
    import datetime
     
    correct = 0
    incorrect = 0
     
    with open("resume.md5", "r") as file:
        source = {}
        content = file.read().splitlines()
        for line in content:
            x = line.split(" ")
            source[x[1]] = x[0]
     
    date1 = datetime.datetime.now()
     
    for key, value in source.items():
     
        filename = f'D:/Test/Rep_B/{key}'
        with open(filename, 'rb') as open_file:
     
            content = open_file.read()
            # hasher.update(content)
            hasher = hashlib.md5(content)
            md5 = hasher.hexdigest()
            print(f'le fichier {filename} à un md5 de {md5} pour une source de {value}')
     
        if md5 == value:
            correct += 1
        else:
            incorrect += 1
            with open(r'D:/Test/error.txt', 'a') as er:
                er.write(f'{source[0]}\n')
     
     
    date2 = datetime.datetime.now()
     
    print (f' le nombre de fichier correct est : {correct}')
    print (f' le nombre de fichier incorrect est : {incorrect}')
     
    duree = date2 - date1
    print(f'Durée de la procédure  : {duree}')
    cela fonctionne.

    et voici la version avec tentative de multiprocessing :
    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    import hashlib
    import datetime
    import multiprocessing
     
    with open("resume.md5", "r") as file:
     
        source = []
        content = file.read().splitlines()
        for line in content:
            x = line.split(" ")
            source.append((x[1], x[0]))
     
    date1 = datetime.datetime.now()
     
    def comparemd5(dic):
     
        correct = 0
        incorrect = 0
     
        filename = f'D:/Test/Rep_B/{dic[0]}'
     
        with open(filename, 'rb') as open_file:
     
            content = open_file.read()
            hasher = hashlib.md5(content)
            md5 = hasher.hexdigest()
     
            print(f'le fichier {filename} à un md5 de {md5} pour une source de {dic[1]}')
     
        if md5 == dic[1]:
            correct += 1
        else:
            with open(r'D:/Test/error.txt', 'a') as er:
                er.write(f'{dic[0]}\n')
     
     
     
    if __name__ == '__main__':
        with multiprocessing.Pool(8) as p:
            p.map(comparemd5, source)
        date2 = datetime.datetime.now()
        duree = date2 - date1
        print(f'Durée de la procédure : {duree}')
    cela fonctionne aussi.


    Est-ce que vous pensez que ma seconde procédure tient la route, ou faut-il que je change des choses.

    Bonne journée à tous

  8. #8
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 480
    Points : 9 277
    Points
    9 277
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Comparer 2 fichiers avec leur MD5 n'est pas forcément une bonne idée, pour 2 raisons:

    - le MD5 possède des collisions. Cela veut dire que 2 fichiers différents peuvent avoir le même MD5. Même si c'est rare, c'est très gênant.

    - si on doit calculer le MD5 à chaque fois, ce calcul nécessitera la lecture totale des 2 fichiers. Mais peut-être que ces 2 fichiers sont différents à partir du 1er octet, auquel cas on perd beaucoup de temps.

    Par contre, si on calcule le hash une seule fois et qu'on s'en sert après plusieurs fois, pourquoi pas. Mais pour être sûr, il faudrait prendre un meilleur hash pour éviter les collisions comme SHA-2.

    Si on veut comparer les contenus de 2 fichiers une seule fois, on peut faire une comparaison par bloc binaire, qui s'arrêtera à la 1ère différence:

    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
    import os
     
    def compfichiers(nfc1, nfc2, lgbuf=32*1024):
        """Compare les 2 fichiers (avec leur chemin), et retourne True seulement 
           s'ils ont un contenu identique (comparaison par blocs d'octets)
        """
        result = False
        if os.path.getsize(nfc1) == os.path.getsize(nfc2):
            with open(nfc1, "rb") as f1, open(nfc2, "rb") as f2: 
                while True:
                    buf1 = f1.read(lgbuf)
                    if len(buf1) == 0:
                        result = True
                        break
                    buf2 = f2.read(lgbuf)
                    if buf1 != buf2:
                        break
        return result

  9. #9
    Membre actif Avatar de FadeToBlack
    Homme Profil pro
    ...
    Inscrit en
    Août 2010
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : ...
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Août 2010
    Messages : 314
    Points : 204
    Points
    204
    Par défaut
    Bonjour Tyrtamo et merci de ces précisions.

    Effectivement, je n'avais pas vu les choses comme cela. Je vais faire des essais avec un SHA-2 ou avec ta méthode, histoire de ne pas mourrir idiot.

    Mais, aussi je voulais avoir ton avis, au-delà du caractère pénible du calcul du MD5, sur la procédure de parallélisme.

    Est-ce comme cela que l'on fait ? N'ais-je pas fait d'erreur ? La partie __main__, ou le reste, peut elle être amélioré pour augmenter les performances.

    Merci de tes précision

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 344
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 344
    Points : 36 865
    Points
    36 865
    Par défaut
    Salut,

    Citation Envoyé par FadeToBlack Voir le message
    Est-ce que vous pensez que ma seconde procédure tient la route, ou faut-il que je change des choses.
    En supposant que vous allez faire çà plusieurs fois, il faut peut être éviter de calculer le hash à chaque fois en gardant dans le "resume", non seulement le nom mais aussi la taille, la date de création, la date de modification histoire de ne recalculer le hash que si...

    De toutes façons quelque soit l'algorithme de hash, il y aura des collisions: vous pourrez conclure que les fichiers sont différents si le hash est différent mais s'il est égal, il faudra comparer block à block (mais filecmp.cmp fait déjà cela pour vous).

    - W

  11. #11
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 480
    Points : 9 277
    Points
    9 277
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Concernant la partie multiprocessing, j'avais suggéré qu'on pouvait gagner du temps en confiant la recherche des fichiers sur disque à un processus séparé, et même de faire les 2 opérations sur Rep_A et Rep_B dans 2 processus qui feront ça en même temps...

    Mais non: en faisant ça (je viens d'essayer), on obtient bien le bon résultat, mais on ne gagne rien en temps! Et pour une bonne raison: quelques soient les processus qui accèdent an même temps aux disques, ils se partagent tous la même ressource matérielle d'accès physique, et c'est ça qui est le goulot d'étranglement.

    Il n'y a donc aucun intérêt en durée de traitement à mettre ça dans des processus séparés.

    Sauf en cas de programme graphique, mais là, on ne le fait pas pour gagner du temps, mais pour éviter le gel du graphique: si c'est ton cas, je peux te proposer une solution.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. conception et technologie d'un processus asynchrone
    Par Dr. Fioko dans le forum Développement Web en Java
    Réponses: 0
    Dernier message: 16/03/2017, 11h11
  2. fork processus zombie et processus orphelin
    Par TuxThePenguin dans le forum C
    Réponses: 16
    Dernier message: 05/10/2015, 20h28
  3. Réponses: 2
    Dernier message: 27/08/2012, 09h17
  4. Processus père attend processus fils
    Par prgasp77 dans le forum Administration système
    Réponses: 12
    Dernier message: 10/09/2009, 15h00

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