¿Qué hilos comparten en general?


20

Bueno, esta es una pregunta general. Y si alguien quiere hacer que su implementación sea específica, preferiré cosas relacionadas con Unix. Pero primero necesita saber los siguientes problemas en general:

Leí que el proceso único puede tener múltiples hilos. Múltiples hilos del mismo proceso comparten cosas entre ellos. Quiero saber qué comparten y qué no. Teniendo en cuenta que el proceso se compone de espacio de direcciones, pila, montón, variables globales, código, datos, recursos del sistema operativo, ¿cuál de ellos es compartido por los subprocesos? Tengo las siguientes conjeturas:

  1. Variables globales: he leído la variable global de recursos compartidos de subprocesos. Además, mientras programaba en Java y C #, hice hilos para compartir variables de nivel de clase. Por lo tanto, creo que los subprocesos comparten variables globales (aunque no estoy seguro de si los conceptos en lenguajes de programación de alto nivel se traducen como si fueran hechos de bajo nivel de sistema operativo).

  2. Montón: dado que la variable global se almacena en el montón, el montón se comparte entre los subprocesos.

  3. Pila: dado que cada subproceso puede tener su propia secuencia / código de ejecución, debe tener su propia pila en la que pueda empujar / reventar el contenido de su contador de programa (cuando suceden llamadas a funciones y retornos). Entonces los hilos del mismo proceso no comparten pila.

Ahora no estoy seguro de compartir lo siguiente

  1. Espacio de direcciones: no estoy seguro de lo que cuenta exactamente en el espacio de direcciones. Pero supongo que el espacio de direcciones generalmente se usa en el contexto de procesos, no en subprocesos. Y dado que todos los subprocesos del mismo proceso residen en el mismo espacio de direcciones que el proceso principal, se dice que los subprocesos comparten espacio de direcciones. (¿Pero luego mantienen una pila diferente dentro del mismo espacio de direcciones?)

  2. Recursos del sistema operativo: supongo que esto puede ser muy específico de la implementación. Por ejemplo, el proceso primario puede dar selectivamente el mismo archivo a algunos de sus subprocesos y no a todos. ¿O me equivoco y los recursos del sistema operativo significan algo más que archivos?

  3. Código: los subprocesos pueden tener un código diferente, por lo que compartir código no siempre es el caso.

  4. Datos: no estoy seguro de qué considerar bajo los datos. Pero seguro que las variables globales se comparten entre los hilos. Y seguro de que las variables locales no se comparten de manera similar.

En general, estoy considerablemente confundido debido a los términos vagos, las súper generalizaciones realizadas en los libros de Sistemas operativos y los detalles específicos de implementación adicionales que se proporcionan en línea. Así que estoy tratando de encontrar alguna respuesta que pueda satisfacerme.

Respuestas:


13

En general, cada subproceso tiene sus propios registros (incluido su propio contador de programa), su propio puntero de pila y su propia pila. Todo lo demás se comparte entre los hilos que comparten un proceso.

En particular , se considera que un proceso consiste en un conjunto de subprocesos que comparten un espacio de direcciones, un montón, datos estáticos y segmentos de código, y descriptores de archivo * .

Un espacio de direcciones es simplemente el mapeo de direcciones lógicas a piezas específicas de memoria física. Entonces, cuando decimos que todos los subprocesos en un proceso comparten el mismo espacio de direcciones, queremos decir que al acceder a una variable fooen el ámbito global, todos los subprocesos verán la misma variable. Del mismo modo, los subprocesos pueden estar ejecutando un punto diferente en el código en un momento determinado, pero a todos se les permite llamar a la función global bar(), que corresponderá a la misma función para cada subproceso en el proceso.

La mayoría de los sistemas operativos modernos han agregado una noción de almacenamiento local de subprocesos , que son variables de alcance global que no se comparten. El ejemplo habitual del uso de esto es para la variable errno. Esa es una variable única de alcance global, pero en la mayoría de los sistemas operativos modernos cada subproceso recibe su propia copia local, por lo que un error en una llamada a la biblioteca en un subproceso no afectará el comportamiento de otros subprocesos.

* Hay un estado de proceso adicional compartido por todos los subprocesos en un proceso, como la identificación del proceso, el manejo de la señal y los bloqueos de archivos. Para obtener una lista completa del estado del proceso compartido por los subprocesos, debe consultar la documentación de la implementación específica de subprocesos. Por ejemplo, la página de manual de pthreads .


4

Los hilos surgen en dos perspectivas: sistemas operativos y lenguajes de programación. En ambos casos, hay alguna variación en los atributos que tiene un hilo.

Una definición mínima de un hilo es que son cosas que suceden en secuencia, una cosa tras otra.

En un modelo de ejecución de máquina típico, cada subproceso tiene su propio conjunto de registros de propósito general y su propio contador de programa. Si la máquina establece un registro específico como un puntero de pila, hay una copia por hilo.

Desde la perspectiva del sistema operativo, lo mínimo que debe hacer un sistema operativo para admitir subprocesos es proporcionar una forma de cambiar entre ellos. Esto puede suceder automáticamente ( multitarea preventiva o solo cuando el hilo realiza una solicitud explícita (multitarea cooperativa; en ese caso, los hilos a veces se denominan fibras ). También hay modelos híbridos con rendimientos preventivos y cooperativos, por ejemplo, preferencia entre hilos de diferentes grupos o tareas pero rendimientos explícitos entre subprocesos del mismo grupo / tarea. Cambiar entre subprocesos implica como mínimo guardar los valores de registro del subproceso anterior y restaurar los valores de registro del nuevo subproceso.

En un sistema operativo multitarea que proporciona aislamiento entre tareas (o procesos , puede tratar estos términos como sinónimos en un contexto de SO), cada tarea tiene sus propios recursos, en particular el espacio de direcciones, pero también archivos abiertos, privilegios, etc. El aislamiento tiene para ser proporcionado por el núcleo del sistema operativo , una entidad que está por encima de los procesos. Cada tarea normalmente tiene al menos un subproceso; una tarea que no ejecuta código no es de mucha utilidad. El sistema operativo puede o no admitir múltiples subprocesos en la misma tarea; por ejemplo, el Unix original no lo hizo. Una tarea aún puede ejecutar varios subprocesos organizando el cambio entre ellos; esto no requiere ningún privilegio especial. Esto se llama " hilos de usuario", Especialmente en un contexto Unix. Hoy en día, la mayoría de los sistemas Unix proporcionan hilos de kernel, en particular porque es la única forma de tener múltiples hilos del mismo proceso ejecutándose en diferentes procesadores.

La mayoría de los recursos del sistema operativo, aparte del tiempo de cálculo, están asociados a tareas, no a subprocesos. Algunos sistemas operativos (por ejemplo, Linux) delimitan explícitamente las pilas, en cuyo caso cada subproceso tiene el suyo; pero hay sistemas operativos en los que el núcleo no sabe nada acerca de las pilas, solo son parte del montón en lo que a él respecta. El núcleo también maneja típicamente un contexto de núcleo para cada hilo, que es una estructura de datos que contiene información sobre lo que el hilo está haciendo actualmente; esto permite que el núcleo maneje múltiples hilos bloqueados en una llamada al sistema al mismo tiempo.

En lo que respecta al sistema operativo, los subprocesos de una tarea ejecutan el mismo código, pero están en diferentes posiciones en ese código (diferentes valores de contador de programa). Puede suceder o no que ciertas partes del código de un programa siempre se ejecuten en subprocesos específicos, pero generalmente hay un código común (por ejemplo, funciones de utilidad) que se puede invocar desde cualquier subproceso. Todos los hilos ven los mismos datos, de lo contrario se considerarían tareas diferentes; Si algunos datos solo pueden ser accedidos por un subproceso en particular, eso generalmente es competencia exclusiva del lenguaje de programación, no del sistema operativo.

En la mayoría de los lenguajes de programación, el almacenamiento se comparte entre subprocesos del mismo programa. Este es un modelo de memoria compartida de programación concurrente; es muy popular, pero también muy propenso a errores, porque el programador debe tener cuidado cuando múltiples hilos pueden acceder a la misma información ya que pueden ocurrir condiciones de carrera . Tenga en cuenta que incluso las variables locales se pueden compartir entre subprocesos: “variable local” (generalmente) significa una variable cuyo nombre solo es válido durante una ejecución de una función, pero otro subproceso puede obtener un puntero a esa variable y acceder a ella.

También hay lenguajes de programación donde cada hilo tiene su propio almacenamiento, y la comunicación entre ellos se realiza mediante el envío de mensajes a través de canales de comunicación. Este es el modelo de transmisión de mensajes de programación concurrente. Erlanges el principal lenguaje de programación que se enfoca en pasar mensajes; su entorno de ejecución tiene un manejo de subprocesos muy liviano, y alienta a los programas escritos con muchos subprocesos de corta duración, en contraste con la mayoría de los otros lenguajes de programación, donde crear un subproceso es una operación relativamente costosa y el entorno de tiempo de ejecución no puede soportar un gran tamaño número de hilos al mismo tiempo. El subconjunto secuencial de Erlang (la parte del lenguaje que ocurre dentro de un hilo, en particular la manipulación de datos) es (principalmente) puramente funcional; por lo tanto, un hilo puede enviar un mensaje a otro hilo que contenga algunos datos y ninguno de ellos debe preocuparse por los datos que el otro hilo modifica mientras lo está utilizando.

Algunos idiomas combinan los dos modelos al ofrecer almacenamiento local de subprocesos, con o sin un sistema de tipos para distinguir la ubicación de almacenamiento local de subprocesos de los globales. El almacenamiento local de subprocesos suele ser una característica conveniente que permite que un nombre variable designe diferentes ubicaciones de almacenamiento en diferentes subprocesos.

Algunos seguimientos (difíciles) que pueden ser de interés para comprender qué son los hilos:

  • ¿Cuál es el mínimo que debe hacer un núcleo para admitir múltiples subprocesos?
  • En un entorno multiprocesador, ¿qué se necesita para migrar un subproceso de un procesador a otro?
  • ¿Qué se necesitaría para implementar múltiples subprocesos cooperativos ( corutinas ) en su lenguaje de programación favorito sin soporte del sistema operativo y sin usar su soporte incorporado, si lo hay? (Tenga en cuenta que la mayoría de los lenguajes de programación carecen de las primitivas necesarias para implementar corutinas dentro de un solo hilo).
  • ¿Cómo sería un lenguaje de programación si tuviera concurrencia pero no un concepto (explícito) de hilos? (Ejemplo principal: el cálculo pi ).

Esto es lo más interesante que he leído en meses.
JSON

2

Eso depende. Si considera los hilos como se define, por ejemplo, por POSIX (y ofrecido por los sistemas Unix) o por Windows (no está familiarizado con el posterior, tendría que preguntar específicamente), entonces eso da su respuesta (esencialmente como explica la respuesta de @WanderingLogic). Linux tiene su propia idea de hilos, usando la clone(2)llamada de sistema no estándar . Ofrece un control bastante detallado de lo que comparten padres e hijos. Va tan lejos como tener fork(2)y vfork(2)esencialmente envolturas alrededor de lo interno clone(2), llamándolo con banderas específicas, es decir, puede crear "hilos" que comparten casi nada con el padre. Consulte su página de manual para obtener más detalles, están disponibles en línea, por ejemplo, aquí . Sí, Linux ofrece hilos de estilo POSIX, pero mucho más además.


0

Los hilos comparten:

  • Espacio de dirección
  • Montón
  • Datos estáticos
  • Segmentos de código
  • Descriptores de archivo
  • Variables globales
  • Procesos hijos
  • Alarmas pendientes
  • Señales y manejadores de señales
  • Informacion de cuenta

Los hilos tienen los suyos:

  • Contador de programa
  • Registros
  • Apilar
  • Estado
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.