¿Para qué proceso es `/ proc / self /`?

40

https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s3-proc-self.html dice

El /proc/self/directorio es un enlace al proceso actualmente en ejecución.

Siempre hay múltiples procesos ejecutándose simultáneamente, entonces, ¿qué proceso es "el proceso actualmente en ejecución"?

¿El "proceso actualmente en ejecución" tiene algo que ver con qué proceso se está ejecutando actualmente en la CPU, considerando el cambio de contexto?

¿El "proceso actualmente en ejecución" no tiene nada que ver con los procesos en primer plano y en segundo plano?

Tim
fuente
15
El proceso que evalúa /proc/self, por supuesto.
Charles Duffy
8
¿A qué persona nos referimos yo y yo ?
Jeffrey Bosboom

Respuestas:

64

Esto no tiene nada que ver con los procesos en primer plano y en segundo plano; solo tiene que ver con el proceso actualmente en ejecución. Cuando el kernel tiene que responder a la pregunta "¿Qué /proc/selfseñala?", Simplemente selecciona el pid programado actualmente , es decir , el proceso actualmente en ejecución (en la CPU lógica actual). El efecto es que /proc/selfsiempre apunta al pid del programa que pregunta; si tu corres

ls -l /proc/self

verá lsel pid, si escribe código que usa /proc/selfese código verá su propio pid, etc.

Stephen Kitt
fuente
13
Esto es "preciso" en cierto sentido, pero no tiene sentido para alguien que no entiende el concepto de "corriente" del núcleo. Una mejor respuesta sería que es el proceso de hacer la llamada al sistema con /proc/selfcomo parte del nombre de ruta en una de sus argumentos.
R ..
1
@R .. eso es lo que destaca la respuesta de ilkkachu , siéntete libre de votar eso, lo hice.
Stephen Kitt
37

El que accede al enlace simbólico (invoca readlink () en él o open () en una ruta a través de él). Se estaría ejecutando en la CPU en ese momento, pero eso no es relevante. Un sistema multiprocesador podría tener varios procesos en la CPU simultáneamente.

Los procesos en primer plano y en segundo plano son en su mayoría una construcción de shell, y tampoco hay un proceso de primer plano único, ya que todas las sesiones de shell en el sistema tendrán uno.

ilkkachu
fuente
27

La redacción podría haber sido mejor, pero una vez más, cualquier redacción que intente componer para expresar la idea de auto referencia será confusa. El nombre del directorio es más descriptivo en mi opinión.

Básicamente, /proc/self/representa el proceso que está leyendo /proc/self/. Entonces, si intenta abrir /proc/self/desde un programa en C, entonces representa ese programa. Si intenta hacerlo desde el shell, entonces es el shell, etc.

Pero, ¿qué sucede si tiene una CPU de cuatro núcleos capaz de ejecutar 4 procesos simultáneamente, de manera real, no multitarea?

Luego, cada proceso verá un /proc/self/real diferente sin poder verse el uno al otro /proc/self/.

¿Como funciona esto?

Bueno, en /proc/self/realidad no es una carpeta. Es un controlador de dispositivo que se expone como una carpeta si intenta acceder a él. Esto se debe a que implementa la API necesaria para las carpetas. El /proc/self/directorio no es lo único que hace esto. Considere carpetas compartidas montadas desde servidores remotos o montando unidades de memoria USB o dropbox. Todos funcionan implementando el mismo conjunto de API que hacen que se comporten como carpetas.

Cuando un proceso intenta acceder /proc/self/al controlador del dispositivo generará su contenido dinámicamente al leer los datos de ese proceso. Por lo tanto, los archivos /proc/self/no existen realmente. Es como un espejo que refleja el proceso que intenta mirarlo.

¿Es realmente un controlador de dispositivo? ¡Parece que estás simplificando demasiado las cosas!

Sí, de verdad lo es. Si quieres ser pedante, es un módulo de kernel. Pero si revisa las publicaciones de usenet en los diversos canales de desarrolladores de Linux, la mayoría de los desarrolladores de kernel usan indistintamente "controlador de dispositivo" y "módulo de kernel". Solía ​​escribir controladores de dispositivos, err ... módulos del núcleo, para Linux. Si desea escribir su propia interfaz /proc/, por ejemplo, si desea un /proc/unix.stackexchange/sistema de archivos que devuelva publicaciones de este sitio web, puede leer sobre cómo hacerlo en el venerable libro "Controladores de dispositivos Linux" publicado por O'Reilly. Incluso está disponible como copia electrónica en línea.

slebetman
fuente
66
/proc/selfno es un controlador de dispositivo, sino que es parte de un sistema de archivos expuesto al núcleo llamado procfs.
Chris Down
1
@ChrisDown: Sí, pero está implementado como un módulo del núcleo, que es la versión de Linux del controlador del dispositivo, incluso hay un ejemplo de implementación de un /proccontrolador basado en el libro venerable "Controladores de dispositivos Linux". Debería saber que implementé uno en la universidad. Probablemente podría haber usado el término "módulo de kernel", pero "controlador de dispositivo" es con lo que la mayoría de la gente está familiarizada y no quiero dar la impresión engañosa de que hay una diferencia significativa entre "módulo de kernel" y "controlador de dispositivo" aparte de la terminología
slebetman
77
@slebetman bueno, procfs no es un módulo per se, solo puede integrarse, nunca integrarse como módulo. Si quiere hilar fino, el pelo de separación es que se trata de un controlador de sistema de archivos, no un controlador de dispositivo
hobbs
10

Es el proceso al que se accede /proc/selfo los archivos / carpetas que contiene.

Tratar cat /proc/self/cmdline. Obtendrá, sorpresa sorpresa, cat /proc/self/cmdline(en realidad, en lugar de un espacio habrá un carácter nulo entre el ty el /) porque será el proceso del gato que accede a este pseudofile.

Cuando haces un ls -l /proc/self, verás el pid del proceso ls en sí. ¿O qué tal ls -l /proc/self/exe? apuntará al ejecutable ls.

O intente esto, para variar:

$ cp /proc/self/cmdline /tmp/cmd
$ hexdump -C /tmp/cmd
00000000  63 70 00 2f 70 72 6f 63  2f 73 65 6c 66 2f 63 6d  |cp./proc/self/cm|
00000010  64 6c 69 6e 65 00 2f 74  6d 70 2f 63 6d 64 00     |dline./tmp/cmd.|
0000001f

o incluso

$ hexdump -C /proc/self/cmdline 
00000000  68 65 78 64 75 6d 70 00  2d 43 00 2f 70 72 6f 63  |hexdump.-C./proc|
00000010  2f 73 65 6c 66 2f 63 6d  64 6c 69 6e 65 00        |/self/cmdline.|
0000001e

Como dije, es el proceso al que se accede /proc/selfo los archivos / carpetas en él.

Viktor Toth
fuente
2

/ proc / self es azúcar sintáctico. Es un atajo para contaminar / proc / y el resultado de la llamada al sistema getpid () (accesible en bash como la metavariable $$). Puede ser confuso, aunque, en el caso de las secuencias de comandos de shell, ya que muchas de las declaraciones invocan otros procesos, completos con los propios PID ... PID que se refieren, en la mayoría de los casos, a procesos muertos. Considerar:

root@vps01:~# ls -l /proc/self/fd
total 0
lrwx------ 1 root root 64 Jan  1 01:51 0 -> /dev/pts/0
lrwx------ 1 root root 64 Jan  1 01:51 1 -> /dev/pts/0
lrwx------ 1 root root 64 Jan  1 01:51 2 -> /dev/pts/0
lr-x------ 1 root root 64 Jan  1 01:51 3 -> /proc/26562/fd
root@vps01:~# echo $$
593

'/ bin / ls' evaluará la ruta al directorio, resolviéndolo como / proc / 26563, ya que ese es el PID del proceso, el proceso / bin / ls recién creado, que lee el contenido del directorio. Pero para cuando el próximo proceso en la tubería, en el caso de la secuencia de comandos de shell, o para cuando regrese la solicitud, en el caso de un shell interactivo, la ruta ya no existe y la salida de información se refiere a un proceso inexistente.

Sin embargo, esto solo se aplica a los comandos externos (los que son archivos de programa ejecutables reales, en lugar de estar integrados en el propio shell). Por lo tanto, obtendrá resultados diferentes si, por ejemplo, utiliza el bloqueo de nombre de archivo para obtener una lista de los contenidos del directorio, en lugar de pasar el nombre de la ruta al proceso externo / bin / ls:

root@vps01:~# ls /proc/self/fd
0  1  2  3
root@vps01:~/specs# echo /proc/self/fd/*
/proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3

En la primera línea, el shell generó un nuevo proceso, '/ bin / ls', a través del exec () syscall, pasando "/ proc / self / fd" como argv [1]. '/ bin / ls', a su vez, abrió el directorio / proc / self / fd y leyó, luego imprimió, su contenido mientras iteraba sobre ellos.

La segunda línea, sin embargo, usa glob () detrás de escena para expandir la lista de nombres de archivo; estos se pasan como una serie de cadenas para hacer eco. (Por lo general, se implementa como un comando interno, pero a menudo también hay un binario / bin / echo ... pero esa parte es realmente irrelevante, ya que echo solo trata con cadenas que nunca alimenta a ninguna llamada al sistema relacionada con los nombres de ruta).

Ahora, considere el siguiente caso:

root@vps01:~# cd /proc/self/fd
root@vps01:~# ls
0  1  2  255

Aquí, el shell, el proceso padre de / bin / ls, ha convertido un subdirectorio de / proc / self en su directorio actual . Por lo tanto, los nombres de ruta relativos se evalúan desde su perspectiva. Mi mejor conjetura es que esto está relacionado con la semántica de archivos POSIX donde puede crear múltiples enlaces duros a un archivo, incluidos los descriptores de archivos abiertos. Esta vez, / bin / ls se comporta de manera similar a echo / proc / $$ / fd / *.

Barry J. Burns
fuente
-2

A medida que el shell invoca programas como ls en procesos separados, / proc / self se mostrará como un enlace simbólico a nnnnn , donde nnnnn es el ID del proceso del proceso ls. Hasta donde yo sé, los shells de uso común no están integrados para leer enlaces simbólicos, pero Perl tiene:

perl -e 'print "/ proc / self link:", readlink ("/ proc / self"), "- pid $$ \ n";'

Entonces / proc / self se comporta como un enlace simbólico, pero el sistema de archivos procfs lo hace "mágicamente" consciente del proceso.

LHP
fuente