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

Windows Discussion :

Explications sur Threads


Sujet :

Windows

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 48
    Par défaut Explications sur Threads
    Bonjour à tous,

    J'ai lu le tutoriel du site sur les threads (de bob), j'ai complètement découvert les threads mais j'ai quand même quelques difficultés à comprendre comment je peux mettre en place ceci avec mon système client/serveur.

    D'après ce que j'ai compris avec un thread je vais pouvoir lancer plusieurs fois une même fonction par exemple, ce qui me permet de lancer deux envois simultanés de fichiers. Jusque là tout va très bien c'est ce que je souhaite faire, voir plus par exemple avec une limite de 5. J'ai compris les idées de synchronisation, mais je me dit que cela est surtout utile pour lancer une action dans un thread et une fois fini executer la seconde dans un autre thread qui attendait.

    Donc mes questions sont les suivantes:

    Si je lance deux fois le même code d'envoi de fichier, cela veut dire que toutes mes variables créées seront les mêmes dans chacun des threads, dans dès que je vais stocker dans une variable un morceau de mon fichier, l'autre va le modifier en même temps (presque), etc...
    Donc comment faire?
    Je connais bien ce système:
    EnterCriticalSection(&Sync); et LeaveCriticalSection, mais si je fais ça pour toute la partie envoi qui est dans une boucle for, le thread va faire ce qu'il à a faire, le second thread va essayer d'accéder à la même partie de la fonction, il ne pourras pas, pendant ce temps il consommera des ressources processeur à ne rien faire, le premier reprendra, le second ne pourra toujours pas accéder vu qu'on est dans une section critique (il ne peut pas faire la chose en même temps), etc...

    Dans en gros il n'y aura qu'un seul thread qui va s'exécuter. Je ne sais pas comment faire en réalité, je suis vraiment novice et je voudrais vraiment comprendre ce que je fais.

    Ensuite dans le tuto j'ai vu cette ligne:
    "De plus, la réalisation d'applications multithread est souvent source d'erreurs. En effet, il ne faut jamais oublier que des instructions situées dans des threads seront exécutées dans un ordre quelconque.".

    Dans si j'ai une suite d'instructions dans ma fonction appelée qui est lancée dans une thread, les instructions ne seront pas exécutées dans l'ordre?

    Désolé pour ces questions qui peuvent paraitre illogiques, mais j'ai du mal avec tout ça, c'est vraiment nouveau pour moi.

    Merci à vous

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 411
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 411
    Par défaut
    Avec le multithreading, tu peux non seulement exécuter X fois simultanément la même fonction, mais aussi exécuter X fonctions différentes. Un programme peut avoir par exemple un thread pour la communication réseau, un autre pour l'interface avec l'utilisateur, et un troisième qui joue de la musique...
    • Chaque thread possède sa propre pile, ce qui veut dire que les variables locales non-statiques ne seront pas partagées. Par contre, les variables statiques ou globales le seront. Généralement, il ne faut pas accéder simultanément à la même ressource, d'où nécessité d'employer les sections critiques. Mais sur un programme en réseau par exemple, X threads peuvent envoyer chacun un fichier par chacun un socket...
    • Les instructions d'un même thread seront toujours exécutées dans l'ordre, mais tu ne peux jamais savoir si elles seront exécutées avant ou après une instruction d'un autre thread... (hors synchronisation, bien sûr).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 48
    Par défaut
    Bonsoir,

    Merci pour ta réponse rapide
    Alors j'ai compris pour l'histoire de la synchro au niveau des threads, en gros on ne peut pas nous garantir que sur deux threads qui exécutent le même code, on avancera aussi vite dans l'un que dans l'autre est ce bien ca?

    Ensuite je ne vois pas trop ce qu'est une variable statique. Pour les variables locales je sais que ce sont les variables déclarées dans une fonction, et les globales déclarées dans le main() en dehors du fonction. Est un #define?

    Ensuite question qui me trote dans la tête aussi.
    Pour mon serveur je vais avoir une boucle qui attend des connexions de clients. En temps normal on aurait tendance à faire cette boucle avec un while(1), mais est ce une bonne idée? Comment gérer cela avec un système d'évènement?

    Et autre question comment passer des paramètres dans la fonction qui est appelée dans la création du thread? J'avais cru lire qu'on pouvait passer une pointeur vers une structure...
    Je pense que je vais devoir passer une structure d'adresse récupérée lors du accept().

    EDIT: D'après ta réponse ci-dessus je n'aurais donc pas besoin d'utiliser EnterCriticalSection() dans la fonction qui sera appelé étant donné que les variables sont séparées. Juste besoin de mettre cela avant les écritures dans la console. Est ce bien ça?
    Un autre point: dans ma fonction recevoirFichier, je fais appelle à d'autres fonctions. Est ce possible de faire appel à d'autres fonctions depuis un thread?
    Existe-t-il un moyen de faire exécuter quelquechose à un thread et de "passer" le résultat à un autre thread (dans un event?).
    Et dernière question (je sais j'en ai beaucoup ): je compte faire une allocation de mémoire avec malloc dans les threads lancés. Est ce que cette ressource sera la même dans les différents threads (je ne sais pas si on peut considérer ca comme une variable locale..., je la verrais plutôt comme globale. Si elle est globale je dois utiliser EnterCriticalSection()? ).
    Ouf c'est tout pour aujourd'hui

    Merci encore à toi

  4. #4
    Membre émérite Avatar de sloshy
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2005
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 728
    Par défaut
    Bonjour,
    Je laisse le soin a Medinoc de parler des threads, ça me fera apprendre davantage sur le sujet

    En C, la portée d'une variable est le bloc dans lequel elle a été déclarée.
    Si la variable n'est déclarée dans aucun bloc, elle est globale a l'ensemble du projet.
    Le mots clefs static permet de changer ces lois.
    Si la variable est déclarée dans une fonction avec le mots clefs static, elle ne sera pas détruite a la fin de l'appel de la fonction.
    La variable ne sera pas accessible en dehors de la fonction ou elle a été déclarée mais lors du rappel de cette fonction, la variable aura conservée la valeur qu'elle avait lors de la dernière exécution.
    Si une variable est déclarée en dehors de toutes fonctions (globale) avec le mots clef static, la portée de la variable est limitée au fichier ou celle-ci a été déclarée (et non a l'ensemble du projet).

    Le define n'est pas une variable, il n'est pas modifiable et pour cause il n'existe pas dans le programme une fois compiler.
    define remplacera dans le fichier texte sa variable par son contenu AVANT la compilation du code (c'est ce qu'on nome une directive preprocesseur).

    main.c

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include "toto.c"
    
    int globale; //Cette variable est accessible partout, meme dans toto.c
    
    int main(void)
    {
        int i; //Cette variable ne pourra être utilisée que dans le main.
        return (42);
    }
    toto.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #define MY_DEFINE "toto\n"
    static int file; //cette variable est accessible dans toto.c (mais pas main.c)
    
    void my_funct(void)
    {
        static int var; //ne sera jamais effacée mais seul my_funct l'utilisera
        write(1, MY_DEFINE, 5); //remplacera MY_DEFINE par "toto\n"
        return ;
    }

    EDIT://

    Je n'avais pas vu la question sur malloc,
    malloc nécessite de declarer un pointeur, si le pointeur est globale alors tu pourra l'utiliser partout, s'il est locale uniquement dans la fonction.
    Même si tu ne free pas ton malloc celui-ci sera toujours allouee en memoire mais tu ne pourra pas lire sont contenu.

    Question a 100 points, lors du rappel d'une fonction qui a fait appel a un malloc non free, est ce que l'ont peut encore atteindre le contenu de cette espace memoire? (une espece de variable statique en plus crade).

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 411
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 411
    Par défaut
    Notes sur les variables:
    • Une variable globale, indépendamment de son qualificateur static qui dans ce cas veut dire autre chose, est toujours dite stockée "en mémoire statique".
    • Une variable locale non-statique est dite stockée "en mémoire automatique", car elle se trouve sur la pile, elle cesse d'exister quand on quitte le bloc où elle a été déclarée.
    • Dans Une variable locale statique, le "statique" est plus important que le "locale". En clair, pour moi c'est comme une variable globale déguisée.

    Par contre, je n'ai pas tellement compris la question à 100 points. La durée de vie d'un bloc alloué (dit "mémoire dynamique") est indépendante de celle des variables automatiques ou statiques. Tant qu'on a un pointeur vers le bloc en question (et que le bloc n'a pas été détruit avec free()), on peut y accéder.

    Sur les threads:
    1. Oui, c'est bien ça.
    2. Voir plus haut.
    3. Typiquement, on utilise une boucle, finie ou non, qui bloque sur une fonction d'attente (pour des sockets, ça bloque sur accept() ou recv()). Ensuite, il faut probablement un moyen de quitter les boucles en question, proprement de préférence.
    4. C'est ça.
    5. Un thread est un flot d'exécution comme un autre, donc la fonction "première" d'un thread peut sans problème appeler d'autres fonctions. En fait, le main() s'exécute dans un thread aussi, tu sais. C'est juste le premier thread du processus.
    6. Dans un programme bien réglé*, le malloc() est automatiquement synchronisé, et les différents blocs mémoire sont indépendants. Simplement, si plusieurs threads possèdent chacun un pointeur sur le même bloc, alors tu dois considérer le bloc comme partagé et le protéger par une section critique.

    *Attention, sous Visual Studio 6, et peut-être 7 aussi, il y a une option à changer dans les options du projet pour indiquer qu'on veut la version multithread de malloc(). Pas de problème sous Visual Studio 8 et supérieur, où la version monothread n'existe plus.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 48
    Par défaut
    Bonjour,

    Merci à tous les deux pour vos réponses, et désolé de ne pas être venu répondre plus tôt.

    Je saisi déjà beaucoup mieux le concept des threads (enfin je dirais peut être plus ça quand je vais commencer à reprogrammer mon programme avec ).

    Par contre je suis sous DevC++ (wxDevCpp 6.10.2) avec MinGW, sais-tu si le malloc est en version multithread par défaut?

    Merci bien, et bonne journée

Discussions similaires

  1. Explication sur thread
    Par hugoclo dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 29/04/2014, 10h01
  2. Explication sur l'utilisation de Thread
    Par pHlegMatikangel dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 23/11/2008, 09h01
  3. [Thread] explication sur les threads
    Par airod dans le forum Général Python
    Réponses: 4
    Dernier message: 16/10/2006, 19h02
  4. Réponses: 28
    Dernier message: 18/08/2003, 11h54
  5. recherches des cours ou des explications sur les algorithmes
    Par Marcus2211 dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 19/05/2002, 22h18

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