Quelles ressources sont partagées entre les threads?
Récemment, j'ai posé une question dans une interview quelle est la différence entre un processus et un thread. Vraiment, je ne savais pas la réponse. J'ai pensé pendant une minute, et a donné un très étrange réponse.
Threads partagent le même espace mémoire, les processus ne sont pas. Après avoir répondu à ce que le recruteur m'a donné un sourire mal et a tiré les questions suivantes à moi:
Q. savez-vous qu'aux secteurs dans lesquels un programme est divisé?
Ma réponse: yep (pensais que c'était facile) de la Pile, de Données, de Code, de Tas
Q. Alors, dites-moi: quels sont les segments ne threads partagent?
Je ne pourrais pas répondre à cela et il a fini en disant tous.
S'il vous plaît, quelqu'un peut-il présenter le bon et impressionnant de réponses pour la différence entre un processus et un thread?
- Les Threads partagent le même virtuelle de l'espace d'adressage, le processus n'en ont pas.
- double possible de Quelle est la différence entre un processus et un thread
Vous devez vous connecter pour publier un commentaire.
Vous êtes à peu près correct, mais threads partagent tous les segments sauf la pile. Les Threads sont indépendants les piles d'appels, cependant la mémoire dans d'autres piles de threads est toujours accessible et, en théorie, vous pourriez organiser un pointeur vers la mémoire dans un autre thread local du cadre de pile (bien que vous devriez trouver un meilleur endroit pour mettre cette mémoire!).
De Wikipédia (je pense que ça ferait une très bonne réponse pour l'interviewer :P)
Quelque chose qui a vraiment besoin d'être souligné, c'est que, il y a deux aspects à cette question - l'aspect théorique et la mise en œuvre d'aspect.
Tout d'abord, regardons l'aspect théorique. Vous avez besoin de comprendre ce qu'un processus est en théorie pour comprendre la différence entre un processus et un thread et ce qui est partagé entre eux.
Nous avons la suite de l'article 2.2.2 Le Classique Modèle de Thread dans Les Systèmes d'Exploitation modernes 3e par Tanenbaum:
Il poursuit:
En outre, il fournit le tableau suivant:
Ci-dessus est ce que vous avez besoin pour les threads de travail. Comme d'autres l'ont souligné, les choses comme les segments d'OS à charge de la mise en œuvre de détails.
Dire à l'enquêteur qu'il dépend entièrement de la mise en œuvre de l'OS.
Prendre Windows x86 par exemple. Il y a seulement 2 segments [1], le Code et les Données. Et ils sont mappés à l'ensemble de 2 GO (linéaire, utilisateur) de l'espace d'adresse. Base=0, Limit=2 GO. Ils aurait fait un x86 mais ne permet pas un segment à la fois en Lecture/Écriture et d'Exécution. Donc, ils ont fait deux, et ensemble CS à point pour le code descripteur, et le reste (DS, ES, SS, etc) au point à l'autre [2]. Mais deux points de la même chose!
La personne que vous interviewer avait fait un postulat caché qu'il/elle n'avait pas d'état, et c'est un truc stupide pour tirer.
Donc en ce qui concerne
Les segments sont pas à la question, au moins sur Windows. Threads partagent l'ensemble de l'espace d'adressage. Il est à seulement 1 segment de pile, SS, et il indique exactement les mêmes choses que les DS, ES, et CS n' [2]. I. e. toute sanglante de l'espace utilisateur. 0-2 GO. Bien sûr, cela ne signifie pas que les threads ont seulement 1 pile. Naturellement, chacun a sa propre pile, mais x86 segments ne sont pas utilisés à cette fin.
Peut-être *nix fait quelque chose de différent. Qui sait. La prémisse de la question est basée sur était cassé.
ntsd notepad
:cs=001b ss=0023 ds=0023 es=0023
Généralement, les Threads sont à la lumière du poids. Si l'on divise la mémoire en trois sections, ce sera: le Code, les données et la Pile.
Chaque processus a son propre code, les données et la pile d'articles et en raison de ce changement de contexte temps est un peu élevé. Afin de réduire les temps de changement de contexte, des gens sont venus avec le concept de thread, qui partage des Données et de segment de code avec d'autres thread/processus et il a son propre segment de PILE.
Un processus de code, des données, des tas et des segments de pile. Maintenant, le Pointeur d'Instruction (IP) d'un fil OU des fils de points sur le segment de code de la procédure. Les données et les tas segments sont partagés par tous les threads. Maintenant, quelle est la superficie de pile? Quelle est en fait la pile? C'est une zone créée par le processus juste pour son fil à utiliser... car les piles peuvent être utilisées dans une méthode beaucoup plus rapide que des tas etc. La pile du processus est divisée entre les threads, c'est à dire si il y a 3 fils, puis la pile du processus est divisé en 3 parties et chacune est donnée à l'3 fils. En d'autres termes, quand nous disons que chaque thread possède sa propre pile, la pile est en fait une partie de la pile du processus de la zone allouée à chaque thread. Lorsqu'un thread termine son exécution, la pile du thread est récupérée par le processus. En fait, non seulement la pile d'un processus est divisée entre les threads, mais l'ensemble des registres qu'un thread utilise comme PS, du PC et de l'état, les registres les registres du processus.
Alors, quand il s'agit de partage, le code, les données et les tas de domaines sont partagés, alors que la pile est juste divisée entre les threads.
Threads partagent le code et les segments de données et le tas, mais ils ne partagent pas la pile.
Threads partagent les données et le code si le processus n'en ont pas. La pile n'est pas partagé pour les deux.
Processus peuvent aussi partager de la mémoire, plus précisément le code, par exemple après un
Fork()
, mais c'est un détail d'implémentation et (système d'exploitation) de l'optimisation. Code partagé par plusieurs processus (espérons-le) de devenir dupliqué sur le premier à écrire le code - ce qui est connu comme copy-on-write. Je ne suis pas sûr à propos de la sémantique exacte pour le code de threads, mais je suppose que le code partagé.1 Le code est logiquement privé, mais peut être partagée pour des raisons de performances.
2 je ne suis pas sûr à 100%.
Threads partagent tout [1]. Il y a un espace d'adressage pour l'ensemble du processus.
Chaque thread possède sa propre pile et les registres, mais de tous les threads " piles sont visibles dans l'espace d'adressage partagé.
Si un thread alloue un objet sur sa pile, et envoie l'adresse à un autre thread, ils vont à la fois avoir l'égalité d'accès à cet objet.
En fait, je viens de remarquer un problème plus vaste: je pense que vous êtes confus deux utilisations du mot segment.
Le format de fichier pour un fichier exécutable (par exemple, ELF) a des sections distinctes, qui peuvent être appelés segments, contenant le code compilé (texte), des données initialisées, l'éditeur de liens symboles, les informations de débogage, etc. Il n'y a pas de tas ou de segments de pile ici, car ceux-ci sont uniquement à l'exécution des constructions.
Ces fichier binaire segments peuvent être mappé dans l'espace d'adressage du processus séparément, avec des autorisations différentes (par exemple, en lecture seule exécutable pour le code/texte, et copie sur écriture non-exécutable pour les données initialisées).
Zones de cet espace d'adressage sont utilisées à différentes fins, comme l'allocation de tas et des piles de threads, par convention (appliqué par votre language runtime des bibliothèques). C'est tout simplement de la mémoire, cependant, et probablement pas segmenté, sauf si vous êtes en cours d'exécution en mode virtuel 8086. Chaque pile du thread est un bloc de mémoire alloué au fil de la création, avec le courant de la pile en haut de l'adresse stockée dans un registre de pointeur de pile, et chaque thread conserve son propre pointeur de pile avec ses autres registres.
[1] OK, je sais: le signal des masques, des TSS/DNT etc. L'adresse de l'espace, y compris tous ses cartographié des segments de programme, sont encore partagés si.
Dans un x86 cadre, on peut diviser que de nombreux segments (jusqu'à 2^16-1). L'ASM directives SEGMENT/prend fin le permet, et les opérateurs SEG et le DÉCALAGE permet l'initialisation des registres de segment. CS:IP sont généralement initialisé par le chargeur, mais pour la DS, ES, SS la demande est responsable de l'initialisation.
De nombreux environnements de permettre à la soi-disant "simplifié segment de définitions", comme .code, .de données, .sev, .pile etc. et, également selon le "modèle de mémoire" (petite, grande, compacte, etc.) le chargeur initialise les registres de segment en conséquence. Généralement .de données, .sev, .pile et d'autres segments d'habitude (je n'ai pas fait cela depuis 20 ans donc je ne me souviens pas de tous) sont regroupés dans un même groupe - c'est pourquoi, généralement, DS, ES et SS points de la même zone, mais ce n'est que pour simplifier les choses.
En général, tous les registres de segment peut avoir des valeurs différentes au moment de l'exécution.
Donc, la question de l'entrevue était de droit: qui un de le CODE, les DONNÉES et la PILE sont partagées entre les threads. Tas de gestion est quelque chose d'autre, c'est simplement une séquence d'appels à l'OS. Mais que faire si vous ne disposez pas d'un OS, comme dans un système embarqué - pouvez-vous encore de new/delete dans votre code?
Mon conseil aux jeunes gens de lire quelques bons assemblage de programmation livre. Il semble que l'université curriculae sont assez pauvres à cet égard.
Thread partager le tas (il y a des recherches sur fil segment spécifique), mais la mise en œuvre actuelle de partager le tas. (le code)
Dans les processus de tous les threads système de partage de ressources comme la Mémoire du tas etc. tandis que le Thread a sa propre pile
De sorte que votre sna devrait être la mémoire du tas qui tous les threads partagent un processus.
Extrait De: Le Linux Programming Interface): Interface de Linux et UNIX Manuel de Programmation Système , Michael Kerrisk, page 619