Para qual processo `/ proc / self /`?

40

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

O /proc/self/diretório é um link para o processo em execução no momento.

Sempre há vários processos sendo executados simultaneamente; portanto, qual é o "processo em execução no momento"?

O "processo em execução no momento" tem algo a ver com o processo em execução na CPU, considerando a alternância de contexto?

O "processo em execução no momento" não tem nada a ver com os processos em primeiro plano e em segundo plano?

Tim
fonte
15
O processo que avalia /proc/self, é claro.
Charles Duffy
8
A que pessoa eu e eu nos referimos?
Jeffrey Bosboom

Respostas:

64

Isso não tem nada a ver com processos em primeiro plano e em segundo plano; isso só tem a ver com o processo em execução no momento. Quando o kernel precisa responder à pergunta “O que /proc/selfaponta para isso?”, Ele simplesmente escolhe o pid agendado atualmente , ou seja , o processo em execução no momento (na CPU lógica atual). O efeito é que /proc/selfsempre aponta para o pid do programa solicitante; se você correr

ls -l /proc/self

você verá lso pid; se você escrever um código que use /proc/selfesse código, verá seu próprio pid etc.

Stephen Kitt
fonte
13
Isso é "preciso" em um sentido, mas não é significativo para alguém que não entende o conceito de "corrente" do kernel. Uma resposta melhor seria que é o processo de fazer a chamada de sistema com /proc/selfcomo parte do caminho em um de seus argumentos.
R ..
11
@R .. é isso que a resposta de ilkkachu destaca, sinta-se à vontade para votar em um deles - eu fiz.
Stephen Kitt
36

Aquele que acessa o link simbólico (chama readlink () nele ou abre () em um caminho através dele). Ele estaria rodando na CPU no momento, mas isso não é relevante. Um sistema multiprocessador pode ter vários processos na CPU simultaneamente.

Os processos em primeiro plano e em segundo plano são principalmente uma construção de shell e também não há nenhum processo em primeiro plano, pois todas as sessões de shell no sistema terão uma.

ilkkachu
fonte
27

A redação poderia ter sido melhor, mas, novamente, qualquer redação que você tentar compor para expressar a idéia de auto-referência será confusa. O nome do diretório é mais descritivo na minha opinião.

Basicamente, /proc/self/representa o processo que está lendo /proc/self/. Portanto, se você tentar abrir a /proc/self/partir de um programa C, ele representará esse programa. Se você tentar fazê-lo a partir do shell, então é o shell etc.

Mas e se você tiver uma CPU quad core capaz de executar 4 processos simultaneamente, de verdade, sem multitarefa?

Então, cada processo verá um /proc/self/real diferente, sem poder ver um ao outro /proc/self/.

Como é que isso funciona?

Bem, /proc/self/não é realmente uma pasta. É um driver de dispositivo que se expõe como uma pasta se você tentar acessá-lo. Isso ocorre porque implementa a API necessária para pastas. O /proc/self/diretório não é a única coisa que faz isso. Considere pastas compartilhadas montadas a partir de servidores remotos ou a montagem de pen drives ou dropbox USB. Todos eles funcionam implementando o mesmo conjunto de APIs que os fazem se comportar como pastas.

Quando um processo tenta acessar /proc/self/o driver de dispositivo, ele gera seu conteúdo dinamicamente, lendo os dados desse processo. Portanto, os arquivos /proc/self/realmente não existem. É como um espelho que reflete de volta no processo que tenta olhar para ele.

É realmente um driver de dispositivo? Parece que você está simplificando demais as coisas!

Sim, é mesmo. Se você quer ser pedante, é um módulo do kernel. Mas se você verificar as postagens da usenet nos vários canais de desenvolvedores Linux, a maioria dos desenvolvedores de kernel usa "driver de dispositivo" e "módulo de kernel" de forma intercambiável. Eu costumava escrever drivers de dispositivo, err ... módulos do kernel, para Linux. Se você deseja escrever sua própria interface /proc/, digamos, por exemplo, que deseja um /proc/unix.stackexchange/sistema de arquivos que retorne postagens deste site, você pode ler sobre como fazê-lo no venerável livro "Linux Device Drivers" publicado por O'Reilly. Está disponível até como cópia eletrônica online.

slebetman
fonte
6
/proc/selfnão é um driver de dispositivo, mas faz parte de um sistema de arquivos exposto ao kernel chamado procfs.
Chris Baixo
11
@ ChrisDown: Sim, mas é implementado como um módulo do kernel - que é a versão do driver de dispositivo do linux - há até um exemplo de implementação de um /procdriver baseado no venerável livro "Linux Device Drivers". Eu deveria saber, eu implementei um na faculdade. Provavelmente eu poderia ter usado o termo "módulo do kernel", mas "driver de dispositivo" é o que a maioria das pessoas conhece e não quero dar a impressão enganosa de que há uma diferença significativa entre "módulo do kernel" e "driver de dispositivo" além da terminologia.
Slebetman
7
@slebetman bem, procfs não é um módulo em si, só pode ser incorporado, nunca construído como um módulo. Se você quiser cabelos divididos, o cabelo a divisão é que é um driver de sistema de arquivos, e não um driver de dispositivo
hobbs
10

É o processo que estiver acessando /proc/selfou os arquivos / pastas nele.

Tente cat /proc/self/cmdline. Você receberá, surpresa surpresa, cat /proc/self/cmdline(na verdade, em vez de um espaço, haverá um caractere nulo entre the te the /) porque será o processo do gato acessando esse pseudofile.

Quando você faz um ls -l /proc/self, verá o próprio processo ls. Ou que tal ls -l /proc/self/exe; apontará para o ls executável.

Ou tente isso, 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

ou mesmo

$ 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 eu disse, é o processo que estiver acessando /proc/selfou os arquivos / pastas nele.

Viktor Toth
fonte
2

/ proc / self é açúcar sintático. É um atalho para contatenar / proc / e o resultado do syscall getpid () (acessível no bash como o metavariável $$). Pode ser confuso, no entanto, no caso de scripts de shell, pois muitas das instruções invocam outros processos, completos com os próprios PIDs ... PIDs que se referem, na maioria das vezes, a processos mortos. 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' avaliará o caminho para o diretório, resolvendo-o como / proc / 26563, pois esse é o PID do processo - o recém-criado processo / bin / ls - que lê o conteúdo do diretório. Porém, no momento em que o próximo processo no pipeline, no caso de scripts de shell, ou no momento em que o prompt retornar, no caso de um shell interativo, o caminho não existe mais e a saída de informações se refere a um processo inexistente.

Isso se aplica apenas a comandos externos, no entanto (aqueles que são arquivos de programas executáveis ​​reais, em vez de incorporados ao próprio shell). Portanto, você obterá resultados diferentes se, digamos, usar globbing de nome de arquivo para obter uma lista do conteúdo do diretório, em vez de passar o nome do caminho para o processo 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

Na primeira linha, o shell gerou um novo processo, '/ bin / ls', via syscall exec (), passando "/ proc / self / fd" como argv [1]. '/ bin / ls', por sua vez, abriu o diretório / proc / self / fd e leu e depois imprimiu seu conteúdo conforme iterava sobre eles.

A segunda linha, no entanto, usa glob () nos bastidores para expandir a lista de nomes de arquivos; estes são passados ​​como uma matriz de strings para eco. (Geralmente implementado como um comando interno, mas geralmente também existe um binário / bin / echo ... mas essa parte é realmente irrelevante, pois o echo está apenas lidando com cadeias de caracteres que nunca alimenta qualquer syscall relacionada aos nomes de caminho.)

Agora, considere o seguinte caso:

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

Aqui, o shell, o processo pai de / bin / ls, transformou um subdiretório de / proc / self em seu diretório atual . Assim, nomes de caminho relativos são avaliados a partir de sua perspectiva. Meu melhor palpite é que isso esteja relacionado à semântica do arquivo POSIX, na qual você pode criar vários links físicos para um arquivo, incluindo qualquer descritor de arquivo aberto. Portanto, desta vez, / bin / ls se comporta de maneira semelhante a echo / proc / $$ / fd / *.

Barry J. Burns
fonte
-2

Como o shell chama programas como ls em processos separados, / proc / self aparecerá como um link simbólico para nnnnn , onde nnnnn é o ID do processo ls. Até onde eu sei, os shells comumente usados ​​não têm base para ler links simbólicos, mas o Perl tem:

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

Portanto, o / proc / self se comporta como um link simbólico, mas o sistema de arquivos procfs o torna "magicamente" com reconhecimento de processo.

LHP
fonte