Для какого процесса `/ proc / self /`?

40

https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s3-proc-self.html говорит

/proc/self/Каталог представляет собой ссылку на текущий процесс.

Всегда есть несколько процессов, запущенных одновременно, поэтому какой процесс является «текущим процессом»?

Имеет ли «текущий процесс» какое-либо отношение к тому, какой процесс в данный момент выполняется на процессоре, учитывая переключение контекста?

Разве «текущий процесс» не имеет ничего общего с передним и фоновым процессами?

Тим
источник
15
Процесс, который оценивает /proc/self, конечно.
Чарльз Даффи
8
К какому человеку я и я обращаемся?
Джеффри Босбом

Ответы:

64

Это не имеет ничего общего с передним и фоновым процессами; это имеет отношение только к текущему процессу. Когда ядро ​​должно ответить на вопрос «На что /proc/selfуказывает?», Оно просто выбирает текущий запланированный pid , то есть текущий запущенный процесс (на текущем логическом процессоре). Эффект /proc/selfвсегда указывает на pid запрашивающей программы; если вы бежите

ls -l /proc/self

вы увидите lspid, если вы напишите код, использующий /proc/selfэтот код, увидите свой собственный pid и т. д.

Стивен Китт
источник
13
Это «точно» в некотором смысле, но не имеет смысла для того, кто не понимает в ядре понятие «текущий». Лучше ответ был бы , что это процесс делает системный вызов с /proc/selfкак часть имени пути в одном из своих аргументов.
R ..
1
@R .. вот что подчеркивает ответ ilkkachu , не стесняйтесь, чтобы поднять этот вопрос - я сделал.
Стивен Китт
37

Тот, который обращается к символической ссылке (вызывает readlink () для него или open () для пути через него). В то время он работал бы на процессоре, но это не имеет значения. Многопроцессорная система может иметь несколько процессов на процессоре одновременно.

Передний план и фоновые процессы в основном представляют собой конструкцию оболочки, и уникального переднего процесса также не существует, поскольку все сеансы оболочки в системе будут иметь один.

ilkkachu
источник
27

Формулировка могла бы быть лучше, но опять же любая формулировка, которую вы пытаетесь составить, чтобы выразить идею самореференции, будет сбивать с толку. Название каталога более наглядно, на мой взгляд.

В основном, /proc/self/представляет процесс, который читает /proc/self/. Поэтому, если вы попытаетесь открыть /proc/self/программу на C, она будет представлять эту программу. Если вы попытаетесь сделать это из оболочки, то это оболочка и т. Д.

Но что, если у вас есть четырехъядерный процессор, способный одновременно выполнять 4 процесса, а не многозадачность?

Тогда каждый процесс будет видеть по-другому, /proc/self/не видя друг друга /proc/self/.

Как это работает?

Ну, /proc/self/это не совсем папка. Это драйвер устройства, который раскрывает себя как папку, если вы пытаетесь получить к нему доступ. Это потому, что он реализует API, необходимый для папок. /proc/self/Каталог не единственное , что делает это. Рассмотрите общие папки, смонтированные с удаленных серверов или подключающие USB-накопители или Dropbox. Все они работают, реализуя один и тот же набор API, который заставляет их вести себя как папки.

Когда процесс пытается получить доступ /proc/self/к драйверу устройства, он будет генерировать его содержимое динамически, читая данные из этого процесса. Таким образом, файлы в /proc/self/действительности не существуют. Это как зеркало, отражающее процесс, который пытается на него взглянуть.

Это действительно драйвер устройства? Похоже, вы слишком упрощаете вещи!

Да, это действительно так. Если вы хотите быть педантичным, это модуль ядра. Но если вы просматриваете сообщения usenet на различных каналах разработчиков Linux, большинство разработчиков ядра используют «драйвер устройства» и «модуль ядра» взаимозаменяемо. Раньше я писал драйверы устройств, ошибки ... модули ядра, для Linux. Если вы хотите написать свой собственный интерфейс /proc/, скажем, например, вам нужна /proc/unix.stackexchange/файловая система, которая возвращает сообщения с этого сайта, вы можете прочитать о том, как это сделать, в почтенной книге «Драйверы устройств Linux», опубликованной О'Рейли. Это даже доступно как softcopy онлайн.

slebetman
источник
6
/proc/selfне является драйвером устройства, а является частью файловой системы, называемой ядром procfs.
Крис Даун
1
@ChrisDown: Да, но он реализован в виде модуля ядра - версии драйвера устройства для linux - /procв почтенной книге «Драйверы устройств Linux» есть даже пример реализации основанного драйвера. Я должен знать, я реализовал один в колледже. Я, вероятно, мог бы использовать термин «модуль ядра», но «драйвер устройства» - это то, с чем большинство людей знакомо, и я не хочу создавать ложное впечатление, что существует существенная разница между «модулем ядра» и «драйвером устройства». кроме терминологии.
slebetman
7
@slebetman Хорошо, procfs не является модулем как таковым, его можно только встроить , но никогда не создавать как модуль. Если вы хотите разделить волосы, нужно разделить их на то, что это драйвер файловой системы, а не драйвер устройства
hobbs
10

Это какой-то процесс, к которому происходит доступ /proc/selfили файлы / папки в нем.

Попробуй cat /proc/self/cmdline. Вы получите, к удивлению cat /proc/self/cmdline, (фактически, вместо пробела между символами и tи будет пустой символ /), потому что это будет процесс cat, обращающийся к этому псевдофайлу.

Когда вы сделаете ls -l /proc/self, вы увидите pid самого процесса ls. Или как насчет ls -l /proc/self/exe; он будет указывать на исполняемый файл ls.

Или попробуйте это, для разнообразия:

$ 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

или даже

$ 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

Как я уже сказал, это происходит в зависимости от того, к какому процессу осуществляется доступ /proc/selfили к файлам / папкам в нем.

Виктор Тот
источник
2

/ proc / self - это синтаксический сахар. Это ярлык для соединения с / proc / и результатом системного вызова getpid () (доступного в bash как метавариабельная $$). Это может сбить с толку, в случае сценариев оболочки, так как многие операторы вызывают другие процессы, в комплекте с собственными PID ... PID, которые чаще всего ссылаются на мертвые процессы. Рассмотреть возможность:

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» оценит путь к каталогу, разрешив его как / proc / 26563, поскольку это PID процесса - недавно созданный процесс / bin / ls - который считывает содержимое каталога. Но к тому времени, когда следующий процесс в конвейере, в случае сценариев оболочки или ко времени возврата приглашения, в случае интерактивной оболочки, путь больше не существует, и вывод информации относится к несуществующему процессу.

Однако это относится только к внешним командам (которые являются фактическими исполняемыми программными файлами, а не встроены в саму оболочку). Таким образом, вы получите другие результаты, если, скажем, будете использовать глобализацию имени файла для получения списка содержимого каталога, а не передавать имя пути во внешний процесс / 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

В первой строке оболочка порождает новый процесс, '/ bin / ls', через системный вызов exec (), передавая "/ proc / self / fd" как argv [1]. «/ bin / ls», в свою очередь, открыл каталог / proc / self / fd и прочитал, а затем распечатал его содержимое, повторяя их.

Вторая строка, однако, использует glob () за кулисами, чтобы расширить список имен файлов; они передаются как массив строк для эха. (Обычно реализуется как внутренняя команда, но часто также есть двоичный файл / bin / echo ... но эта часть на самом деле не имеет значения, так как echo имеет дело только со строками, которые он никогда не передает в любой системный вызов, связанный с путевыми именами.)

Теперь рассмотрим следующий случай:

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

Здесь оболочка, родительский процесс / bin / ls, сделала подкаталог / proc / self своим текущим каталогом . Таким образом, относительные пути оцениваются с его точки зрения. Я думаю, что это связано с семантикой файлов POSIX, где вы можете создать несколько жестких ссылок на файл, включая любые дескрипторы открытого файла. Так что на этот раз / bin / ls ведет себя подобно echo / proc / $$ / fd / *.

Барри Дж. Бернс
источник
-2

Когда оболочка вызывает программы типа ls в отдельных процессах, / proc / self будет отображаться как символическая ссылка на nnnnn , где nnnnn - это идентификатор процесса процесса ls. Насколько я знаю, обычно используемые оболочки не имеют встроенной функции для чтения символических ссылок, но Perl имеет:

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

Таким образом, / proc / self ведет себя как символическая ссылка, но файловая система procfs делает ее «магически» ориентированной на процессы.

КТТ
источник