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

C Discussion :

pthread dans boucle for et mémoire utilisée


Sujet :

C

  1. #21
    Membre émérite
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Points : 2 601
    Points
    2 601
    Par défaut
    Citation Envoyé par darkwall_37 Voir le message
    Merci pour ta réponse picodev.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Si tu veux un affichage séquentiel alors un des moyens est qu'au lieu d'afficher les données directement un thread (pourquoi pas le principal) s'occupe de récupérer les données et de les afficher dans l'ordre une fois le boulot fini
    Ce que je souhaite justement c'est avoir l'état d'avancement en temps réel de l'éxecution de la copie. Si j'ai bien compris ce que tu voulais dire par ta phrase qui suggère donc l'affichage post traitement tel un fichier de log par exemple ?
    Il faut penser autrement.
    Tu crées un nombre fixe de threads (adpaté à la machine qui fait tourner ton programme) qui vont faire la copie. Si tu veux une évolution en RT du travail accompli, alors le plus simple est que chaque thread puisse mettre à jour une variable dédiée que le thread principal va lire de temps à autre pour afficher l'avancement (communication inter thread). Une fois tout le boulot fini, le thread principal join les threads secondaires pour les terminer (par exemple).

  2. #22
    Membre confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    Par défaut
    Je crois voir dans le principe ce que tu proposes.

    En somme, est-ce que ce tu me proposes est la chose suivante ?

    Je crée une nouvelle fonction copie faisant appel à une sous fonction copie ne contenant que le code de la boucle ( qui permet de faire la copie )
    La fonction copie créera un thread qui fera appel à la sous fonction copie
    Il faudra que je crée une autre sous fonction d'affichage qui mettra à jour l'ensemble des valeurs ( Pourquoi un thread par valeur ? Performance ou question de conception intrinsèque à l'utilisation d'un thread ? )
    La fonction copie créera un autre thread qui fera appel à la sous fonction affichage
    Et ensuite il faut que je trouve un moyen de partager les valeurs mises à jour par la sous fonction copie pour la sous fonction affichage afin que je puisse avoir les valeurs en temps réél ?

    Voilà ce que je comprends de ce que tu m'as dis en "algo"

    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
     
    Sous Fonction affichage
        Récupération de la mise à jour des variables de la sous fonction copie gérée par thread1
        afficher ces variables
    Fin Sous fonction affichage 
     
    Sous Fonction copie
        Execution de la copie
        Mise à jour des variables
    Fin Sous Fonction copie
     
    Fonction copie
        déclaration/initialisation des variables à mettre à jour pendant la copie
        thread1 qui prend en charge la sous fonction copie
        thread2 qui prend en charge la sous fonction affichage
        Joindre le thread1
        Joindre le thread2
    Fin fonction copie
    Si c'est bien ce que tu proposes, comment puis-je partager des valeurs entre threads ? Mutex ?

    AHAHA oui je sais ce que tu te dis, pas tous les jours facile d'expliquer un concept à un gogol xD
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  3. #23
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    picodev pensait peut-être plus à diviser la tâche du worker thread en section indépendantes exécutables en parallèle. Si tu fais des opérations sur les éléments d'un tableau de taille T, par exemple, et qu'elles sont réalisables indépendamment les unes des autres, alors tu peux scinder le tableau en n parties et faire traiter à chaque thread numéro i les éléments dans l'intervalle [i * T / n, (i + 1) * T / n[. Sur une machine avec au moins autant de coeurs ou processeurs que de threads instanciés, le programme est en théorie n fois plus rapide.

    Par contre j'entends parler de parallélisme et de copie, on cause bien de copie en mémoire ? Non parce que paralléliser l'entrée-sortie c'est le truc à éviter, sauf application spécifique il n'y a au final qu'un disque, sortie standard, socket, etc...


    Citation Envoyé par darkwall_37 Voir le message
    Et je comprends que le code que j'ai écris est absurde pour mon besoin.
    Pour ton besoin, dans un cadre purement applicatif, honnêtement je pense que le multithreading est overkill. Appelle printf tous les n tours de boucle et tu obtiendras un programme simple, concis et fiable qui fait efficacement ce qu'on lui demande.

    Dans un cadre pédagogique en revanche, l'exercice est intéressant donc on continue.


    Citation Envoyé par darkwall_37 Voir le message
    Techniquement, je ne vois pas comment demander au thread désormais crée hors de la boucle de se "reveiller" pour afficher les valeurs mises à jour pendant l'execution de la boucle de traitement.
    A moins d'utiliser un mutex dans la boucle de traitement qui serait relié au thread d'affichage et qui reveille ce thread lorsqu'il reçoit le message d'unlock ?

    Je t'avoue comme je ne connais pas très bien le sujet, je suis probablement en train de dire n'importe quoi...
    Non tu te poses les bonnes questions.

    Imagine deux personnes en train de faire la vaisselle : l'une lave les assiettes puis les pose sur l'égouttoir et l'autre les prend puis les essuie. Chacun est à sa tâche, à son rythme, et ne se mêle pas du travail de l'autre, celui qui essuie ne dit pas à son camarade comment laver et vice-versa... jusqu'à ce qu'ils doivent se coordonner pour accéder à l'égouttoir ! L'égouttoir est une ressource partagée, dont les accès sont mutuellement exclusifs (tu vois où je veux en venir ? ).

    Il faut que tu définisses clairement les tâches de chacun, que tu identifies ton égouttoir, et que tu en synchronises les accès. Commence avec un mutex, c'est le plus simple (il y a des problèmes inhérents à cette implémentation que je n'évoquerai pas, mais les threads POSIX sont franchement bien foutus et en pratique avec deux threads ça devrait passer crème) : demande le verrou associé à ta ressource partagée lorsque tu y accèdes en lecture et/ou écriture (ton thread bloquera tant qu'il n'est pas disponible), réalise tes opérations pui relâche le verrou. Tu auras besoin de toute la famille pthread_mutex_*. N'oublie pas de relâcher et détruire ton mutex lorsque tu n'en as plus l'usage.

    Le multithreading, c'est franchement difficile. Accroche-toi.

  4. #24
    Membre émérite
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Points : 2 601
    Points
    2 601
    Par défaut
    Citation Envoyé par darkwall_37 Voir le message
    Je crois voir dans le principe ce que tu proposes.

    En somme, est-ce que ce tu me proposes est la chose suivante ?

    Je crée une nouvelle fonction copie faisant appel à une sous fonction copie ne contenant que le code de la boucle ( qui permet de faire la copie )
    La fonction copie créera un thread qui fera appel à la sous fonction copie
    Il faudra que je crée une autre sous fonction d'affichage qui mettra à jour l'ensemble des valeurs ( Pourquoi un thread par valeur ? Performance ou question de conception intrinsèque à l'utilisation d'un thread ? )
    La fonction copie créera un autre thread qui fera appel à la sous fonction affichage
    Et ensuite il faut que je trouve un moyen de partager les valeurs mises à jour par la sous fonction copie pour la sous fonction affichage afin que je puisse avoir les valeurs en temps réél ?

    [...]
    Citation Envoyé par Matt_Houston Voir le message
    picodev pensait peut-être plus à diviser la tâche du worker thread en section indépendantes exécutables en parallèle. Si tu fais des opérations sur les éléments d'un tableau de taille T, par exemple, et qu'elles sont réalisables indépendamment les unes des autres, alors tu peux scinder le tableau en n parties et faire traiter à chaque thread numéro i les éléments dans l'intervalle [i * T / n, (i + 1) * T / n[. Sur une machine avec au moins autant de coeurs ou processeurs que de threads instanciés, le programme est en théorie n fois plus rapide.

    Par contre j'entends parler de parallélisme et de copie, on cause bien de copie en mémoire ? Non parce que paralléliser l'entrée-sortie c'est le truc à éviter, sauf application spécifique il n'y a au final qu'un disque, sortie standard, socket, etc...
    [...]
    Tu as bien résumé mon idée

    Avant d'essayer de paralléliser un programme il faut bien repérer où cela apporte un gain.

  5. #25
    Membre confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    picodev pensait peut-être plus à diviser la tâche du worker thread en section indépendantes exécutables en parallèle. Si tu fais des opérations sur les éléments d'un tableau de taille T, par exemple, et qu'elles sont réalisables indépendamment les unes des autres, alors tu peux scinder le tableau en n parties et faire traiter à chaque thread numéro i les éléments dans l'intervalle [i * T / n, (i + 1) * T / n[. Sur une machine avec au moins autant de coeurs ou processeurs que de threads instanciés, le programme est en théorie n fois plus rapide.

    Par contre j'entends parler de parallélisme et de copie, on cause bien de copie en mémoire ? Non parce que paralléliser l'entrée-sortie c'est le truc à éviter, sauf application spécifique il n'y a au final qu'un disque, sortie standard, socket, etc...




    Pour ton besoin, dans un cadre purement applicatif, honnêtement je pense que le multithreading est overkill. Appelle printf tous les n tours de boucle et tu obtiendras un programme simple, concis et fiable qui fait efficacement ce qu'on lui demande.

    Dans un cadre pédagogique en revanche, l'exercice est intéressant donc on continue.




    Non tu te poses les bonnes questions.

    Imagine deux personnes en train de faire la vaisselle : l'une lave les assiettes puis les pose sur l'égouttoir et l'autre les prend puis les essuie. Chacun est à sa tâche, à son rythme, et ne se mêle pas du travail de l'autre, celui qui essuie ne dit pas à son camarade comment laver et vice-versa... jusqu'à ce qu'ils doivent se coordonner pour accéder à l'égouttoir ! L'égouttoir est une ressource partagée, dont les accès sont mutuellement exclusifs (tu vois où je veux en venir ? ).

    Il faut que tu définisses clairement les tâches de chacun, que tu identifies ton égouttoir, et que tu en synchronises les accès. Commence avec un mutex, c'est le plus simple (il y a des problèmes inhérents à cette implémentation que je n'évoquerai pas, mais les threads POSIX sont franchement bien foutus et en pratique avec deux threads ça devrait passer crème) : demande le verrou associé à ta ressource partagée lorsque tu y accèdes en lecture et/ou écriture (ton thread bloquera tant qu'il n'est pas disponible), réalise tes opérations pui relâche le verrou. Tu auras besoin de toute la famille pthread_mutex_*. N'oublie pas de relâcher et détruire ton mutex lorsque tu n'en as plus l'usage.

    Le multithreading, c'est franchement difficile. Accroche-toi.

    Par contre j'entends parler de parallélisme et de copie, on cause bien de copie en mémoire ? Non parce que paralléliser l'entrée-sortie c'est le truc à éviter, sauf application spécifique il n'y a au final qu'un disque, sortie standard, socket, etc...
    Non, je ne souhaite pas être en mesure de lancer deux copies de fichiers en simultanée, je te rassure xD. La copie dont je parle est de la copie de fichier.

    Pour ton besoin, dans un cadre purement applicatif, honnêtement je pense que le multithreading est overkill. Appelle printf tous les n tours de boucle et tu obtiendras un programme simple, concis et fiable qui fait efficacement ce qu'on lui demande.

    Dans un cadre pédagogique en revanche, l'exercice est intéressant donc on continue.
    C'est déjà ce que je faisais avant d'essayer d'implémenter la technique du thread. Alors attention, je ne souhaite pas utilser le thread pour dire hé oh, je sais utiliser du thread à n'importe quelle sauce. J'ai cru comprendre que cela était le seul moyen pour avoir un affichage temps réel de valeur au sein d'un traitement séquentiel. C'est tout ce que je veux, comme dans une GUI ou on voit en temps réel la barre de progression, les valeurs et ainsi de suite se mettre à jour. Sauf que ça se passe dans une console pour le moment. Après je pensais à utilser les threads pour mettre en cache le buffer de la prochaine volée pendant le buffer n-1 se décharge dans le fichier. Mais c'est une autre histoire.

    Plutôt trépasser que d'arrêter maintenant =)

    Imagine deux personnes en train de faire la vaisselle : l'une lave les assiettes puis les pose sur l'égouttoir et l'autre les prend puis les essuie. Chacun est à sa tâche, à son rythme, et ne se mêle pas du travail de l'autre, celui qui essuie ne dit pas à son camarade comment laver et vice-versa... jusqu'à ce qu'ils doivent se coordonner pour accéder à l'égouttoir ! L'égouttoir est une ressource partagée, dont les accès sont mutuellement exclusifs (tu vois où je veux en venir ? ).
    Sinon dieu inventa la femme pour ce problème. Pas besoin de thread. Ok je sors.

    Le multithreading, c'est franchement difficile. Accroche-toi.
    J'essaye =), la preuve toutes mes questions saugrenues =). Par contre, en ce qui me concerne, dans les tutos que j'ai pu lire, on nous lâche du code presque immédiatement sans expliquer fondamentalement même brievement ce que cela implique. Ce que je trouve dommage, car on finit par faire n'importe quoi comme moi sans comprendre vraiment ce qui se passe durant l'execution. Alors il est vrai que je peux aussi allé m'acheter un livre qui traite du sujet sérieusement et arrêter de me plaindre XD.

    Je regarde tout ça et je vois ce que j'en sors.
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  6. #26
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Il est indispensable de déporter l'opération bloquante pour maintenir la réactivité de l'interface pour autant que l'utilisateur puisse faire autre chose dans le même temps. S'il reste purement spectateur d'une barre de progression, c'est pas vraiment utile (mais j'imagine que tu veux complexifier l'application par la suite).

    Le truc à saisir avec les threads c'est qu'hors des sections critiques leurs exécutions sont totalement décorrélées, et peuvent être préemptées à tout moment. Il faut vraiment épouser le point de vue de chaque thread avant de se risquer à des suppositions sur le fonctionnement global du programme.

  7. #27
    Membre émérite
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Points : 2 601
    Points
    2 601
    Par défaut
    Citation Envoyé par darkwall_37 Voir le message
    [...]
    C'est déjà ce que je faisais avant d'essayer d'implémenter la technique du thread. Alors attention, je ne souhaite pas utilser le thread pour dire hé oh, je sais utiliser du thread à n'importe quelle sauce. J'ai cru comprendre que cela était le seul moyen pour avoir un affichage temps réel de valeur au sein d'un traitement séquentiel. C'est tout ce que je veux, comme dans une GUI ou on voit en temps réel la barre de progression, les valeurs et ainsi de suite se mettre à jour. Sauf que ça se passe dans une console pour le moment. Après je pensais à utilser les threads pour mettre en cache le buffer de la prochaine volée pendant le buffer n-1 se décharge dans le fichier. Mais c'est une autre histoire.
    [...]
    Il y a aussi les callbacks.

    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
     
    typedef void (*callback_t)(void *);
     
    struct work {
      size_t from;
      size_t to;
     
      size_t current;
     
      callback_t start;
      callback_t progress;
      callback_t end;
     
      void *user_data;
    };
     
    void start(void *user_data)
    {
      puts("Starting");
    }
     
    void progress(void *user_data)
    {
      struct work *work=user_data;
      printf("Progress : %5.1f%%\r", (1+work->current-work->from)*100.0/(work->to-work->from));
      fflush(stdout);
    }
     
    void end(void *user_data)
    {
      puts("\nEnd");
    }
     
    void do_work(struct work *work, void *user_data)
    {
      work->start(user_data);
      for(size_t i=work->from; i<work->to; ++i) {
        work->current=i;
        sleep(rand()%3);
        work->progress(user_data);
      }
      work->end(user_data);
    }
     
    int main(void)
    {
      struct work work = {.from=10, .to=20, .start=start, .progress=progress, .end=end};
     
      do_work(&work, &work);
     
      return 0;
    }

Discussions similaires

  1. Réponses: 9
    Dernier message: 15/09/2006, 19h08
  2. [débutant] Pb dans boucle For
    Par Sam 069 dans le forum Access
    Réponses: 2
    Dernier message: 11/09/2006, 13h10
  3. Réponses: 3
    Dernier message: 04/08/2006, 19h24
  4. problème dans boucle for de lecture de fichier ini
    Par chourmo dans le forum Delphi
    Réponses: 3
    Dernier message: 06/07/2006, 09h31
  5. [JLabel] JLabel dans boucle for
    Par clairenes dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 06/01/2006, 00h47

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