/ proc / self /`用于哪个进程?


40

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

/proc/self/目录是当前正在运行的进程的链接。

总是有多个进程同时运行,那么哪个进程是“当前正在运行的进程”?

考虑上下文切换,“当前正在运行的进程”与CPU上当前正在运行的进程有什么关系吗?

“当前正在运行的进程”与前台进程和后台进程无关吗?


15
/proc/self当然,评估的过程。
查尔斯·达菲

8
你这人指什么?
Jeffrey Bosboom '16

Answers:


64

这与前台和后台进程无关。它只与当前正在运行的进程有关。当内核必须回答“ /proc/self指向什么?”的问题时,它只选择当前调度的pid当前正在运行的进程(在当前逻辑CPU上)。结果是/proc/self总是指向询问程序的pid。如果你跑

ls -l /proc/self

您会看到ls的pid,如果您编写的代码使用/proc/self该代码,则会看到其自己的pid等。


13
从某种意义上说,这是“准确的”,但对于不了解内核的“当前”概念的人而言,则没有意义。一个更好的答案是,它的过程使系统调用/proc/self作为它的一个参数的路径名的一部分。
R.,

1
@R ..就是ilkkachu的答案所强调的,随时可以批评那个-我做到了。
史蒂芬·基特

36

访问符号链接的对象(在其上调用readlink()或通过它的路径上的open())。它将当时在CPU上运行,但这无关紧要。多处理器系统可能同时在CPU上有多个进程。

前台和后台进程主要是一个shell构造,也没有独特的前台进程,因为系统上的所有shell会话都将拥有一个。


27

措词本来可以更好,但是您尝试组成的任何表达自我参照的措词都会使人困惑。我认为该目录的名称更具描述性。

基本上,它/proc/self/代表正在阅读的过程/proc/self/。因此,如果您尝试/proc/self/从C程序打开,则它代表该程序。如果您尝试从外壳进行操作,则为外壳等。

但是,如果您有一个四核CPU能够同时运行4个进程,而不是真正执行多任务处理,该怎么办?

然后,每个过程将看到一个/proc/self/真实的不同,而无法看到彼此的/proc/self/

这是如何运作的?

好吧,/proc/self/实际上不是文件夹。它是一种设备驱动程序,如果尝试访问它,它本身会将其公开为文件夹。这是因为它实现了文件夹所需的API。该/proc/self/目录是不是做这个的嘛。考虑从远程服务器安装的共享文件夹或安装USB拇指驱动器或保管箱的共享文件夹。它们都通过实现使它们的行为像文件夹一样的同一组API来工作。

当进程尝试访问时/proc/self/,设备驱动程序将通过从该进程读取数据来动态生成其内容。因此,其中的文件/proc/self/实际上并不存在。有点像一面镜子,可以反射试图查看它的过程。

真的是设备驱动程序吗?您听起来好像在简化事情!

是的,确实如此。如果您想学究的话,它是一个内核模块。但是,如果您查看各种Linux开发人员渠道上的usenet帖子,则大多数内核开发人员会互换使用“设备驱动程序”和“内核模块”。我曾经为Linux写设备驱动程序,错误的内核模块。如果您想在中编写自己的界面/proc/,例如说您想要一个/proc/unix.stackexchange/文件系统来返回此网站上的帖子,则可以在O'Reilly出版的古老的“ Linux Device Drivers”一书中阅读有关如何进行操作的信息。它甚至可以作为在线软拷贝获得。


6
/proc/self不是设备驱动程序,而是一个称为的内核暴露文件系统的一部分procfs
克里斯·

1
@ChrisDown:是的,但是它是作为内核模块实现的-这是linux的设备驱动程序版本- /proc在古老的“ Linux设备驱动程序”一书中甚至有一个基于驱动程序的示例实现。我应该知道,我在大学里实施了一个。我可能本来可以用术语“内核模块”来代替,但是“设备驱动程序”是大多数人所熟悉的,我不想给人以误解的印象,即“内核模块”和“设备驱动程序”之间存在显着差异。除了术语。
slebetman '16

7
@slebetman好,procfs 本身不是模块,只能内置,而不能作为模块构建。如果您要分割头发,则要分割的头发是文件系统驱动程序,而不是设备驱动程序
hobbs

10

无论碰巧正在访问的是哪个过程,/proc/self还是其中的文件/文件夹。

尝试cat /proc/self/cmdline。您会惊奇地发现,cat /proc/self/cmdline(实际上,而不是空格之间,t和之间将有一个空字符/),因为它将是访问此伪文件的cat进程。

执行时ls -l /proc/self,您将看到ls进程本身的pid。或怎么样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中可以作为元变量$$访问)的结果的快捷方式。在shell脚本的情况下,它可能会引起混乱,因为许多语句调用其他进程,并带有自己的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进程-读取目录的内容。但是,在shell脚本的情况下,到管道中的下一个进程,或者在交互式shell的情况下,到提示返回时,路径已不存在,并且信息输出指向不存在的进程。

但是,这仅适用于外部命令(与内置于外壳本身相反的是实际的可执行程序文件)。因此,如果使用文件名遍历获取目录内容列表,而不是将路径名传递给外部进程/ 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

在第一行中,shell通过exec()系统调用生成了一个新进程'/ bin / ls',并将“ / proc / self / fd”作为argv [1]传递。反过来,“ / bin / ls”打开目录/ proc / self / fd并依次遍历读取/打印其内容。

但是,第二行在后台使用glob()来扩展文件名列表。这些作为字符串数组传递以进行回显。(通常以内部命令的形式实现,但是通常还有一个/ bin / echo二进制文件……但是那部分实际上是无关紧要的,因为echo只处理字符串,它从不馈送给任何与路径名相关的syscall。

现在,考虑以下情况:

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

在这里,shell / bin / ls 的父进程,将/ proc / self的子目录作为其当前目录。因此,从其角度评估相对路径名。我最好的猜测是,这与POSIX文件的语义有关,您可以在其中创建到文件的多个硬链接,包括任何打开的文件描述符。因此,这次,/ bin / ls的行为类似于echo / proc / $$ / fd / *。


-2

像在单独的进程LS壳所调用的程序,的/ proc /自将显示为一个符号链接NNNNN,其中NNNNN是LS进程的进程ID。据我所知,常用的shell没有内置的用于读取符号链接的内容,但是Perl具有:

perl -e'print“ / proc / self链接:”,readlink(“ / proc / self”),“-pid $$ \ n”;'

因此,/ proc / self表现为符号链接,但是procfs文件系统使它“神奇地”知道了过程。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.