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 :

les Threads et leur memory stack


Sujet :

C#

  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut les Threads et leur memory stack
    Je suis en train de lire cet article qui explique le multithreading:
    http://www.albahari.com/threading/
    Je remercie encore au passage Jerede pour cet excelent lien !

    Une chose que je ne comprends pas bien. L'auteur dit :

    The CLR assigns each thread its own memory stack so that local variables are kept separate.
    Puis il explique qu'un membre static peut etre partagé entre les 2 Threads :

    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
    class ThreadTest 
    {
      static bool done;    // Static fields are shared between all threads
     
      static void Main()
      {
        new Thread (Go).Start();
        Go();
      }
     
      static void Go()
      {
        if (!done) { done = true; Console.WriteLine ("Done"); }
      }
    }
    Mais alors, si chaque thread a sa propre memory stack, comment se fait-il qu'ils puissent se partager un membre statique ou non?

    Où est stocké un membre statique? Est ce que ca veut dire qu'un membre statique est stocké dans le processus et non dans le thread?

    Merci d'avance pour vos explications.

  2. #2
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Points : 8 082
    Points
    8 082
    Par défaut
    http://www.yoda.arachsys.com/csharp/memory.html
    -Each local variable (ie one declared in a method) is stored on the stack. That includes reference type variables - the variable itself is on the stack, but remember that the value of a reference type variable is only a reference (or null), not the object itself. Method parameters count as local variables too, but if they are declared with the ref modifier, they don't get their own slot, but share a slot with the variable used in the calling code. See my article on parameter passing for more details.
    -Instance variables for a reference type are always on the heap. That's where the object itself "lives".
    -Instance variables for a value type are stored in the same context as the variable that declares the value type. The memory slot for the instance effectively contains the slots for each field within the instance. That means (given the previous two points) that a struct variable declared within a method will always be on the stack, whereas a struct variable which is an instance field of a class will be on the heap.
    -Every static variable is stored on the heap, regardless of whether it's declared within a reference type or a value type. There is only one slot in total no matter how many instances are created. (There don't need to be any instances created for that one slot to exist though.) The details of exactly which heap the variables live on are complicated, but explained in detail in an MSDN article on the subject.
    Pour compléter un peu, la question ne se pose pas dans ton exemple en fait. Il n'y a pas de variables stockées dans la Stack pour Go puisqu'il n'y a ni paramètres ni variables locales...

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    ok merci pour l'info, je pense avoir à peu pret compris.
    Donc j'en déduit que ce qui est stocké sur le tat (heap) est partagé entre tous les threads du processus non?

    Je m'embrouille encore un peu avec ref vu que dans mon esprit, à part les structs et certains types de base (et encore), tout dans c# n'est que reference ("pointeur") vers des objets...

  4. #4
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Points : 8 082
    Points
    8 082
    Par défaut
    Citation Envoyé par giova_fr Voir le message
    ok merci pour l'info, je pense avoir à peu pret compris.
    Donc j'en déduit que ce qui est stocké sur le tat (heap) est partagé entre tous les threads du processus non?

    Je m'embrouille encore un peu avec ref vu que dans mon esprit, à part les structs et certains types de base (et encore), tout dans c# n'est que reference ("pointeur") vers des objets...
    Pour la question la réponse est oui.

    Pour ce qui est du ref, il faut bien comprendre qu'il sert lorsque la fonction modifie le paramètre. Si tu passes un type référence, tu peux le modifier (c'est a dire le faire pointer vers un autre objet) car c'est le pointeur que tu passes enfait!
    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
     
    void Main()
    {
    	var obj1 = new MyClass(1);
    	Console.WriteLine(obj1);
    	Func1(obj1);
    	Console.WriteLine(obj1); //Affiche 1, le pointeur n'a pas été affecté
    	Func2(ref obj1);
    	Console.WriteLine(obj1); //Affiche 3, le pointeur a été affecté
    }
     
    void Func1(MyClass myClass) // On passe une copie du pointeur
    {
    	myClass = new MyClass(2);
    }
     
    void Func2(ref MyClass myClass) // On passe le pointeur original
    {
    	myClass = new MyClass(3);
    }
     
    public class MyClass
    {
    	private int _val;
     
    	public MyClass(int val)
    	{
    		_val = val;
    	}
     
    	public override String ToString()
    	{
    		return String.Format("MyClass #{0}",_val);
    	}
    }
    Lors de l'execution de ce code:
    On a trois MyClass dans le heap. On a un pointeur obj1 dans la stack de Main.
    Quand on appelle Func1 on rajoute un deuxieme pointeur dans la stack qui pointe aussi vers le meme objet que obj1
    Quand on appelle Func2 on ne crée pas un troisième pointeur dans la stack, c'est obj1 qu'est passé

  5. #5
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    Encore merci pour ta réponse, c'est vraiment sympa !

    Mais alors que se passe t'il dans Func1? hypothese :
    Func1 instancie un nouveau pointeur local myClass qu'il initialise avec l'adresse de l'objet passé en parametre (Main.obj1)?

    Ca expliquerai pourquoi on peut modifier l'objet passé en parametre, mais qu'on est sur un pointeur different de Main.obj1

  6. #6
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Points : 8 082
    Points
    8 082
    Par défaut
    Enfait quand tu appelles Func1(obj1), il y'a une copie de obj1 qu'est faite, cette copie est ajoutée à la stack et c'est elle qui est dans le contexte de Func1 sous le nom myClass

Discussions similaires

  1. Réponses: 2
    Dernier message: 19/02/2011, 12h04
  2. Les Threads... J'en remet une couche :)
    Par Higestromm dans le forum C++
    Réponses: 5
    Dernier message: 17/11/2004, 12h19
  3. Gestion des message windows dans les threads
    Par billyboy dans le forum Windows
    Réponses: 5
    Dernier message: 06/10/2003, 17h25
  4. Question simple sur les threads :)
    Par momox dans le forum C++Builder
    Réponses: 2
    Dernier message: 15/06/2003, 04h13
  5. question sur les variables globales et les thread posix
    Par souris_sonic dans le forum POSIX
    Réponses: 5
    Dernier message: 13/06/2003, 13h59

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