Si los subprocesos comparten el mismo PID, ¿cómo se pueden identificar?

98

Tengo una consulta relacionada con la implementación de subprocesos en Linux.

Linux no tiene un soporte de subprocesos explícito. En el espacio de usuario, podríamos usar una biblioteca de subprocesos (como NPTL) para crear subprocesos. Ahora, si usamos NPTL, es compatible con el mapeo 1: 1.

El kernel usará la clone()función para implementar subprocesos.

Supongamos que he creado 4 hilos. Entonces significaría que:

  • Habrá 4 task_struct.
  • Dentro de task_struct, habrá una disposición para compartir recursos según los argumentos para clonar (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND).

Ahora tengo la siguiente consulta:

  1. ¿Los 4 subprocesos tendrán el mismo PID? Si alguien puede explicar cómo se comparten los PID.
  2. ¿Cómo se identifican los diferentes hilos? ¿Existe algún concepto de TID (ID de hilo)?
SPSN
fuente

Respuestas:

274

Los cuatro hilos tendrán el mismo PID pero solo cuando se vean desde arriba. Lo que usted (como usuario) llama un PID no es lo que el núcleo (mirando desde abajo) llama un PID.

En el kernel, cada hilo tiene su propio ID, llamado PID (aunque posiblemente tendría más sentido llamarlo TID, o ID de hilo) y también tienen un TGID (ID de grupo de hilo) que es el PID del hilo que inició todo el proceso.

De manera simplista, cuando se crea un nuevo proceso , aparece como un hilo en el que tanto el PID como el TGID son el mismo (nuevo) número.

Cuando un subproceso inicia otro subproceso, ese subproceso iniciado obtiene su propio PID (por lo que el programador puede programarlo de forma independiente) pero hereda el TGID del subproceso original.

De esa manera, el kernel puede programar subprocesos independientemente del proceso al que pertenecen, mientras que los procesos (ID de grupo de subprocesos) se le informan.

La siguiente jerarquía de subprocesos puede ayudar (a) :

                      USER VIEW
 <-- PID 43 --> <----------------- PID 42 ----------------->
                     +---------+
                     | process |
                    _| pid=42  |_
                  _/ | tgid=42 | \_ (new thread) _
       _ (fork) _/   +---------+                  \
      /                                        +---------+
+---------+                                    | process |
| process |                                    | pid=44  |
| pid=43  |                                    | tgid=42 |
| tgid=43 |                                    +---------+
+---------+
 <-- PID 43 --> <--------- PID 42 --------> <--- PID 44 --->
                     KERNEL VIEW

Puede ver que comenzar un nuevo proceso (a la izquierda) le brinda un nuevo PID y un nuevo TGID (ambos configurados con el mismo valor), mientras que comenzar un nuevo hilo (a la derecha) le brinda un nuevo PID mientras mantiene el mismo TGID como el hilo que lo inició.


(a) Temblar de asombro ante mis impresionantes habilidades gráficas :-)

paxdiablo
fuente
20
Para su información, getpid()devuelve tgid:, asmlinkage long sys_getpid(void) { return current->tgid;}como se muestra en www.makelinux.com/
Duke
6
@Duke - wow, por eso no pude encontrar una gettgid(2)función. Y getpid()no devolverá el TID (el "PID" del hilo), y ahí es donde gettid(2)entra. De esta manera puedo saber si estamos en el hilo principal o no.
Tomasz Gandor
2
Esto lleva a otro punto interesante: entonces, si los subprocesos y procesos se manejan por igual dentro del kernel (aparte del tgid), un proceso de múltiples subprocesos obtendrá en conclusión más tiempo de CPU que uno de un solo subproceso, siempre que ambos tengan el mismo prioridad y ninguno de los subprocesos se detiene por ningún motivo (como esperar un mutex).
Aconcagua
1
@Aconcagua, CFS (el programador completamente justo en Linux) generalmente funciona de esa manera, pero también permite el uso de extensiones de programador de grupo para hacer que la equidad opere en ciertos grupos de tareas en lugar de tareas individuales. En realidad, nunca lo he investigado más que con una mirada superficial.
paxdiablo
'' getpgrp '' para obtener la identificación del grupo
Pengcheng
2

Los subprocesos se identifican mediante PID y TGID (ID de grupo de subprocesos). También saben qué subproceso es padre de quién, por lo que esencialmente un proceso comparte su PID con cualquier subproceso que inicia. Los ID de subprocesos generalmente son administrados por la propia biblioteca de subprocesos (como pthread, etc.). Si se inician los 4 hilos, deben tener el mismo PID. El núcleo mismo manejará la programación de subprocesos y demás, pero la biblioteca es la que administrará los subprocesos (si pueden ejecutarse o no dependiendo de su uso de los métodos de unión y espera de subprocesos).

Nota: Esto es de mi recuerdo del kernel 2.6.36. Mi trabajo en las versiones actuales del kernel está en la capa de E / S, así que no sé si eso ha cambiado desde entonces.

Jesús Ramos
fuente
-6

Linux proporciona a la fork()llamada al sistema la funcionalidad tradicional de duplicar un proceso. Linux también proporciona la capacidad de crear subprocesos utilizando la clone()llamada al sistema. Sin embargo, Linux no distingue entre procesos e subprocesos.

SAUNDARYA KUMAR GUPTA
fuente