Después de leer en this answer y "Linux Kernel Development" de Robert Love y, posteriormente, en la llamada al sistema clone()
, descubrí que los procesos y subprocesos en Linux son (casi) indistinguibles del kernel . Hay algunos ajustes entre ellos (discutidos como "compartir más" o "menos compartir" en la pregunta SO citada), pero todavía tengo algunas preguntas por responder.Distinción entre procesos e hilos en Linux
Recientemente trabajé en un programa que involucraba un par de hilos POSIX y decidí experimentar con esta premisa. En un proceso que crea dos subprocesos, todos los subprocesos obtienen un valor único devuelto por pthread_self()
, sin embargo,, no por getpid()
.
Un programa de ejemplo creé sigue:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <pthread.h>
void* threadMethod(void* arg)
{
int intArg = (int) *((int*) arg);
int32_t pid = getpid();
uint64_t pti = pthread_self();
printf("[Thread %d] getpid() = %d\n", intArg, pid);
printf("[Thread %d] pthread_self() = %lu\n", intArg, pti);
}
int main()
{
pthread_t threads[2];
int thread1 = 1;
if ((pthread_create(&threads[0], NULL, threadMethod, (void*) &thread1))
!= 0)
{
fprintf(stderr, "pthread_create: error\n");
exit(EXIT_FAILURE);
}
int thread2 = 2;
if ((pthread_create(&threads[1], NULL, threadMethod, (void*) &thread2))
!= 0)
{
fprintf(stderr, "pthread_create: error\n");
exit(EXIT_FAILURE);
}
int32_t pid = getpid();
uint64_t pti = pthread_self();
printf("[Process] getpid() = %d\n", pid);
printf("[Process] pthread_self() = %lu\n", pti);
if ((pthread_join(threads[0], NULL)) != 0)
{
fprintf(stderr, "Could not join thread 1\n");
exit(EXIT_FAILURE);
}
if ((pthread_join(threads[1], NULL)) != 0)
{
fprintf(stderr, "Could not join thread 2\n");
exit(EXIT_FAILURE);
}
return 0;
}
(Este fue compilado [gcc -pthread -o thread_test thread_test.c
] en 64 bits Fedora; debido a los tipos de 64 bits utilizados para pthread_t
procedente de <bits/pthreadtypes.h>
, el código requerirá menor cambios para compilar en ediciones de 32 bits)
La salida que se ve es la siguiente:.
[[email protected] ~]$ ./thread_test
[Process] getpid() = 28549
[Process] pthread_self() = 140050170017568
[Thread 2] getpid() = 28549
[Thread 2] pthread_self() = 140050161620736
[Thread 1] getpid() = 28549
[Thread 1] pthread_self() = 140050170013440
[[email protected] ~]$
mediante el uso de schedu ler bloqueo en gdb
, que puede mantener el programa y sus hilos vivo para que pueda captar lo que top
dice que, acaba de mostrar los procesos, es:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
28602 bean 20 0 15272 1112 820 R 0.4 0.0 0:00.63 top
2036 bean 20 0 108m 1868 1412 S 0.0 0.0 0:00.11 bash
28547 bean 20 0 231m 16m 7676 S 0.0 0.4 0:01.56 gdb
28549 bean 20 0 22688 340 248 t 0.0 0.0 0:00.26 thread_test
28561 bean 20 0 107m 1712 1356 S 0.0 0.0 0:00.07 bash
Y cuando se muestran las discusiones, dice:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
28617 bean 20 0 15272 1116 820 R 47.2 0.0 0:00.08 top
2036 bean 20 0 108m 1868 1412 S 0.0 0.0 0:00.11 bash
28547 bean 20 0 231m 16m 7676 S 0.0 0.4 0:01.56 gdb
28549 bean 20 0 22688 340 248 t 0.0 0.0 0:00.26 thread_test
28552 bean 20 0 22688 340 248 t 0.0 0.0 0:00.00 thread_test
28553 bean 20 0 22688 340 248 t 0.0 0.0 0:00.00 thread_test
28561 bean 20 0 107m 1860 1432 S 0.0 0.0 0:00.08 bash
Parece bastante claro que los programas, o quizás el núcleo, tienen una forma distinta de definir los hilos en contraste con los procesos. Cada hilo tiene su propio PID según top
- ¿por qué?
'clone()' es exactamente como Linux implementa ambos hilos y 'fork()'. Todo lo que importa es que hablar con un PID transmitirá la señal a todos los que necesitan saber. Si el kernel asigna identificadores adicionales a los hilos, eso no es de su incumbencia y no afecta la forma en que habla con sus procesos. –
Bueno [enlace] (http://opensourceforgeeks.blogspot.in/2014/03/processes-and-threads-in-linux.html) para ver. –
"* los procesos y los hilos en Linux son (casi) indistinguibles del kernel *" Umm, no es realmente cierto. No hay casi nada que pueda decir sobre cómo funciona el kernel de Linux, que es cierto tanto para los procesos como para los hilos. Posee una vista de vm? Solo procesos Se puede programar? Solo hilos. Tiene una tabla de descriptores de archivos? Solo procesos Tiene una prioridad? Solo hilos. Y así sucesivamente hasta la línea. –