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 connaissais pas la réponse. J'ai pensé pendant une minute et j'ai donné une réponse très étrange.

Les Threads partagent la même mémoire, pas les processus. Après avoir répondu à cela, l'intervieweur m'a donné un sourire maléfique et a tiré les questions suivantes sur moi:

Q. Connaissez-vous les segments dans lesquels un programme est divisé?

Ma réponse: yep (pensé que c'était un simple) pile, données, code, tas

Q. Alors, dites-moi: quels segments partagent les threads?

Je ne pouvais pas répondre à cela et j'ai fini par les dire tous.

S'il vous plait, quelqu'un peut-il présenter les réponses correctes et impressionnantes pour la différence entre un processus et un thread?

209
demandé sur flow2k 2009-11-19 13:45:06

12 réponses

Vous êtes à peu près correct, mais les threads partagent tous les segments sauf la pile. Les Threads ont des piles d'appels indépendantes, mais la mémoire dans d'autres piles de threads est toujours accessible et en théorie, vous pouvez tenir un pointeur vers la mémoire dans le cadre de la pile locale d'un autre thread (bien que vous devriez probablement trouver un meilleur endroit pour mettre cette mémoire!).

133
répondu Greg Hewgill 2009-11-19 10:48:25

De Wikipedia (je pense que cela ferait une très bonne réponse pour l'intervieweur: P)

Les fils diffèrent des fils traditionnels système d'exploitation multitâche processus en ce que:

  • les processus sont généralement indépendants, tandis que les threads existent en tant que sous-ensembles processus
  • les processus contiennent des informations d'état considérables, alors que plusieurs threads dans un État de partage de processus aussi bien comme mémoire et autres ressources
  • les processus ont séparer les espaces d'adressage, alors que les threads partagent espace d'adressage
  • les processus interagissent uniquement par le biais d'inter-processus fournis par le système mécanismes de communication.
  • La commutation de contexte entre threads dans le même processus est généralement plus rapide que la commutation de contexte entre processus.
47
répondu Jorge Córdoba 2011-10-30 12:31:04

Quelque chose qui doit vraiment être souligné est qu'il y a vraiment deux aspects à cette question - l'aspect théorique et l'aspect implémentations.

Tout d'Abord, regardons l'aspect théorique. Vous devez comprendre ce qu'est un processus conceptuellement pour comprendre la différence entre un processus et un thread et ce qui est partagé entre eux.

Nous avons ce qui suit de la section 2.2.2 le modèle de Thread Classique dans Systèmes D'exploitation modernes 3e par Tanenbaum:

Le modèle de processus est basé sur deux concepts indépendants: regroupement et exécution. Parfois, il est utile de les séparer; c'est là que les discussions entrent en jeu....

Il continue:

Une façon de regarder un processus est que c'est un moyen de regrouper les ressources connexes. Un processus a un espace d'adressage contenant du texte et des données du programme, ainsi que d'autres ressources. Ils ressource peut inclure des fichiers ouverts, enfant processus, alarmes en attente, gestionnaires de signaux, informations comptables, et plus encore. En les mettant ensemble sous la forme d'un processus, ils peuvent être gérés plus facilement. L'autre concept d'un processus est un fil d'exécution, généralement raccourci pour juste fil. Le thread a un compteur de programme qui conserve piste de quelle instruction à exécuter ensuite. Il a des registres, qui maintenez ses variables de travail actuelles. Il a une pile qui contient le l'historique d'exécution, avec une image pour chaque procédure appelée mais non encore de retour de. Bien qu'un thread doit s'exécuter dans un processus, le fil et ses processus sont des concepts différents, et peuvent être traités séparément. Les processus sont utilisés pour regrouper les ressources; threads sont les entités planifiées pour l'exécution sur le CPU.

Plus bas, il fournit le tableau suivant:

Per process items             | Per thread items
------------------------------|-----------------
Address space                 | Program counter
Global variables              | Registers
Open files                    | Stack
Child processes               | State
Pending alarms                |
Signals and signal handlers   |
Accounting information        |

Ce qui précède est ce dont vous avez besoin pour que les threads fonctionnent. Comme d'autres l'ont souligné, des choses comme les segments dépendent du système D'exploitation détails de mise en œuvre.

36
répondu Robert S. Barnes 2013-10-22 07:51:07

Dites à l'intervieweur que cela dépend entièrement de la mise en œuvre du système d'exploitation.

Prenez Windows x86 par exemple. Il y a seulement 2 segments [1], Code et données. Et ils sont tous deux mappés à l'ensemble de L'espace d'adressage 2GB (linéaire, utilisateur). Base = 0, limite = 2GB. Ils en auraient fait un mais x86 ne permet pas à un segment d'être à la fois en lecture/écriture et en exécution. Donc, ils ont fait deux, et mis CS pour pointer vers le descripteur de code, et le reste (DS, ES, SS, etc.) pour pointer vers l'autre [2]. Mais deux point pour la même chose!

La personne vous interviewant avait fait une hypothèse cachée qu'il / elle n'a pas déclaré, et c'est un truc stupide à tirer.

Donc en ce qui concerne

Q. Alors, dites-moi quel segment fil partager?

Les segments ne sont pas pertinents à la question, au moins sur Windows. Les Threads partagent tout l'espace d'adressage. Il n'y a que 1 segment de pile, SS, et il pointe vers exactement les mêmes choses que DS, ES et CS [2]. C'est-à-dire Tout l'utilisateur sanglant Espace. 0-2 GO. Bien sûr, cela ne signifie pas que les threads ont seulement 1 pile. Naturellement, chacun a sa propre pile, mais les segments x86 ne sont pas utilisés à cette fin.

Peut-être que * nix fait quelque chose de différent. Qui le sait?. La prémisse sur laquelle la question était basée était brisée.


  1. au moins pour l'espace utilisateur.
  2. à Partir de ntsd notepad: cs=001b ss=0023 ds=0023 es=0023
24
répondu Alex Budovski 2009-11-19 11:54:30

Généralement, les Threads sont appelés processus léger. Si nous divisons la mémoire en trois sections, ce sera: le Code, les données et la pile. Chaque processus a ses propres sections de code, de données et de pile et en raison de ce temps de changement de contexte est un peu élevé. Pour réduire le temps de commutation de contexte, les gens ont mis au point le concept de thread, qui partage les données et le segment de code avec d'autres threads/processus et a son propre segment de pile.

16
répondu Nimish Thakkar 2011-10-05 15:12:53

Un processus a des segments de code, de données, de tas et de pile. Maintenant, le pointeur D'Instruction (IP) d'un thread ou threads pointe vers le segment de code du processus. Les segments de données et de tas sont partagés par tous les threads. Maintenant, quelle est la superficie de pile? Quelle est réellement la zone de la pile? C'est une zone créée par le processus juste pour son fil à utiliser... parce que les piles peuvent être utilisées beaucoup plus rapidement que les tas, etc. La zone de pile du processus est divisée entre les threads, c'est-à-dire s'il y a 3 threads, alors la zone de pile du processus est divisée en 3 parties et chacune est donnée aux 3 threads. En d'autres termes, lorsque nous disons que chaque thread a sa propre pile, cette pile fait en fait partie de la zone de pile de processus 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 tous les registres qu'un thread utilise comme les registres SP, PC et state sont les registres du processus. Ainsi, en ce qui concerne le partage, les zones de code, de données et de tas sont partagées, tandis que la zone de pile est simplement divisée entre les threads.

14
répondu Dhirendra Vikash Sharma 2012-08-20 21:52:00

Les Threads partagent les segments de code et de données et le tas, mais ils ne partagent pas la pile.

12
répondu Kevin Peterson 2009-11-19 10:48:05

Les Threads partagent des données et du code alors que les processus ne le font pas. La pile n'est pas partagée pour les deux.

Les processus

Peuvent également partager de la mémoire, plus précisément du code, par exemple après un Fork(), mais il s'agit d'un détail d'implémentation et d'optimisation (du système d'exploitation). Le Code partagé par plusieurs processus sera (espérons-le) dupliqué lors de la première écriture dans le code - c'est ce qu'on appelle copy-on-write. Je ne suis pas sûr de la sémantique exacte pour le code des threads, mais je suppose partagé code.

           Process   Thread

   Stack   private   private
   Data    private   shared
   Code    private1  shared2

1 Le code est logiquement privée mais peut être partagée pour des raisons de performances. 2 je ne suis pas sûr à 100%.

5
répondu Daniel Brückner 2009-11-19 11:22:53

Threads partagent tout [1]. Il y a un espace d'adressage pour l'ensemble du processus.

Chaque thread a sa propre pile et ses propres registres, mais les piles de tous les threads 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 auront tous deux un accès égal à cet objet.


En fait, je viens de remarquer un problème plus large: je pense que vous confondez deux utilisations du mot segment.

Le format de fichier pour un exécutable (par exemple, ELF) a des sections distinctes, qui peuvent être appelées segments, contenant du code compilé (texte), des données initialisées, des symboles d'éditeur de liens, des informations de débogage, etc. Il n'y a pas de segments de tas ou de pile ici, car ce sont des constructions d'exécution uniquement.

Ces segments de fichiers binaires peuvent être mappés séparément dans l'espace d'adressage du processus, avec des autorisations différentes (par exemple, exécutable en lecture seule pour le code / texte et copie en écriture Non exécutable pour les données initialisées).

Les zones de cet espace d'adressage sont utilisées à des fins différentes, comme l'allocation de tas et les piles de threads, par convention (appliquées par vos bibliothèques d'exécution de langage). Tout est juste de la mémoire, et probablement pas segmenté sauf si vous utilisez en mode virtuel 8086. La pile de chaque thread est un morceau de mémoire alloué au moment de la création du thread, avec l'adresse supérieure de la pile actuelle stockée dans un registre de pointeur de pile, et chaque thread conserve sa propre pile pointeur avec ses autres registres.


[1] OK, je sais: masques de signal, TSS / TSD etc. L'espace d'adressage, y compris tous ses segments de programme mappés, sont toujours partagés.

4
répondu Useless 2009-11-19 11:45:13

Dans un framework x86, on peut diviser autant de segments (jusqu'à 2^16-1). Les directives ASM SEGMENT / ENDS le permettent, et les opérateurs SEG et OFFSET permettent l'initialisation des registres de segment. CS: IP sont généralement initialisés par le chargeur, mais pour DS, ES, SS l'application est responsable de l'initialisation. De nombreux environnements permettent la soi-disant "définitions de segment simplifiées" comme .code, .données, .sev, .pile etc. et, en fonction également du " modèle de mémoire "(Petit, Grand, compact, etc.) le chargeur initialise les registres de segment en conséquence. Généralement .données, .sev, .stack et d'autres segments habituels (Je ne l'ai pas fait depuis 20 ans, donc je ne me souviens pas de tout) sont regroupés dans un seul groupe - c'est pourquoi généralement DS, ES et SS pointe vers la même zone, mais ce n'est que pour simplifier les choses.

En général, tous les registres de segments peuvent avoir des valeurs différentes lors de l'exécution. Donc, la question de l'entrevue était juste: lequel du CODE, des données et de la pile est partagé entre les threads. Tas la gestion est autre chose - c'est simplement une séquence d'appels au système d'exploitation. Mais que faire si vous n'avez pas du tout de système d'exploitation, comme dans un système embarqué-pouvez-vous toujours avoir Nouveau / supprimer dans votre code?

Mon conseil aux jeunes-lisez un bon livre de programmation d'assemblage. Il semble que les programmes universitaires sont assez pauvres à cet égard.

2
répondu George 2011-06-21 07:06:32

Thread partage le tas (il y a une recherche sur le tas spécifique au thread) mais l'implémentation actuelle partage le tas. (et bien sûr le code)

1
répondu Dani 2009-11-19 10:50:51

Dans le processus, tous les threads partagent des ressources système comme la mémoire de tas, etc. while Thread a sa propre pile

Donc, votre ans devrait être une mémoire de tas que tous les threads partagent pour un processus.

0
répondu roshni 2018-05-02 16:25:15