どのプロセスが `/ 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
どの人か私はを参照してください?
ジェフリーボスブーム16

回答:


64

これは、フォアグラウンドプロセスとバックグラウンドプロセスとは関係ありません。現在実行中のプロセスに関係しているだけです。カーネルが「何を/proc/self指しているのか?」という質問に答えなければならない場合、カーネルは単に現在スケジュールされているpidつまり現在実行中のプロセス(現在の論理CPU上)を選択します。その効果は、/proc/self常に質問プログラムのpidを指すことです。あなたが走ったら

ls -l /proc/self

あなたは参照してくださいよls、あなたが使用するコード記述した場合、PIDのを/proc/selfなど、独自のpidを、表示されているコードを


13
これはある意味では「正確」ですが、カーネルの「現在」の概念を理解していない人にとっては意味がありません。より良い答えは、引数の1つにパス名の一部としてシステム呼び出し行うプロセスだということ/proc/selfです。
R ..

1
@R .. ilkkachuの答えが強調しているのは、それを自由に投票してください —私はやりました。
スティーブンキット

36

シンボリックリンクにアクセスするもの(その上でreadlink()を呼び出すか、それを通るパスでopen()を呼び出します)。当時はCPU上で実行されていましたが、それは関係ありません。マルチプロセッサシステムでは、CPU上で複数のプロセスを同時に実行できます。

フォアグラウンドプロセスとバックグラウンドプロセスはほとんどがシェル構造であり、システム上のすべてのシェルセッションには1つがあるため、一意のフォアグラウンドプロセスもありません。


27

言葉遣いはもっと良かったかもしれませんが、自己参照のアイデアを表現するために作成しようとする言葉遣いは、紛らわしくなります。私の意見では、ディレクトリの名前はよりわかりやすいものです。

基本的に、/proc/self/読み取り中のプロセスを表します/proc/self/。したがって/proc/self/、Cプログラムから開こうとすると、そのプログラムを表します。シェルから実行しようとすると、シェルなどになります。

しかし、マルチタスクではなく、実際に4つのプロセスを同時に実行できるクアッドコアCPUがある場合はどうでしょうか。

その後、各プロセスは、/proc/self/お互いのを見ることができずに、実際には異なるものを見るでしょう/proc/self/

これはどのように作動しますか?

まあ、/proc/self/実際にはフォルダではありません。アクセスしようとすると、たまたまフォルダとして公開されるのはデバイスドライバです。これは、フォルダーに必要なAPIを実装するためです。これを行うのは/proc/self/ディレクトリだけではありません。リモートサーバーからマウントされた共有フォルダー、またはUSBサムドライブまたはドロップボックスのマウントを検討してください。これらはすべて、同じAPIセットを実装することで機能し、フォルダーのように動作します。

プロセス/proc/self/がデバイスドライバーにアクセスしようとすると、そのプロセスからデータを読み取って、その内容を動的に生成します。したがって、のファイル/proc/self/は実際には存在しません。それは、それを見ようとするプロセスを振り返る鏡のようなものです。

本当にデバイスドライバーですか?あなたは物事を単純化しすぎているように聞こえます!

はい、そうです。あなたがped慢になりたいのなら、それはカーネルモジュールです。しかし、さまざまなLinux開発者チャンネルでusenetの投稿をチェックすると、ほとんどのカーネル開発者は「デバイスドライバー」と「カーネルモジュール」を同じ意味で使用しています。Linux用のデバイスドライバー、エラー...カーネルモジュールを書くために使用します。/proc/たとえば/proc/unix.stackexchange/、このウェブサイトから投稿を返すファイルシステムが必要な場合など、独自のインターフェイスを作成する場合は、O'Reillyが発行する由緒ある「Linuxデバイスドライバー」の本でその方法を読むことができます。オンラインでソフトコピーとしても入手可能です。


6
/proc/selfはデバイスドライバーではなく、代わりにと呼ばれるカーネル公開ファイルシステムの一部ですprocfs
クリスダウン

1
@ChrisDown:はい、しかしカーネルモジュールとして実装されています-これはデバイスドライバのLinuxバージョンです- /proc由緒ある本「Linuxデバイスドライバ」には、ベースのドライバの実装例さえあります。知っておくべきこと、私は大学でそれを実装しました。代わりに「カーネルモジュール」という用語を使用することもできますが、ほとんどの人は「デバイスドライバー」を使い慣れているので、「カーネルモジュール」と「デバイスドライバー」の間に大きな違いがあるという誤解を招くような印象を与えたくありません用語とは別に。
スリーブマン16

7
@slebetmanよく、procfs モジュール自体ではありません。組み込みのみ可能で、モジュールとしては決してビルドできません。あなたは枝毛にしたい場合は、分割の髪は、それは、ないデバイスドライバ、ファイルシステムドライバだということです
ホッブズ

10

どちらのプロセスがアクセスする/proc/selfか、その中のファイル/フォルダーになります。

試してくださいcat /proc/self/cmdline。あなたは、驚きの驚きを取得しますcat /proc/self/cmdline(実際には、代わりにスペースの間のヌル文字があるでしょう、tそして/それは、この疑似ファイルにアクセスする猫のプロセスであるため)。

を実行する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()syscallの結果(メタ変数$$として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として解決します。これは、ディレクトリの内容を読み取るプロセス(新しく作成された/ bin / lsプロセス)のPIDであるためです。しかし、パイプラインの次のプロセス、シェルスクリプトの場合、またはプロンプトが戻ってくるまで、インタラクティブシェルの場合、パスは存在なくなり、情報出力は存在しないプロセスを参照します。

ただし、これは外部コマンド(シェル自体に組み込まれるのではなく、実際の実行可能プログラムファイルであるコマンド)にのみ適用されます。したがって、たとえば、ファイル名グロビングを使用してディレクトリの内容のリストを取得すると、パス名を外部プロセス/ 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

最初の行では、シェルはexec()syscallを介してargv [1]として「/ proc / self / fd」を渡し、新しいプロセス「/ bin / ls」を生成しました。「/ bin / ls」は、ディレクトリ/ proc / self / fdを開いて、その内容を繰り返して読み取った後、印刷しました。

ただし、2行目では、舞台裏でglob()を使用してファイル名のリストを展開しています。これらはエコーする文字列の配列として渡されます。(通常は内部コマンドとして実装されますが、多くの場合/ bin / 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プロセスのプロセスIDです。私の知る限り、一般的に使用されるシェルにはシンボリックリンクを読み込むための組み込み機能はありませんが、Perlには次の機能があります。

perl -e '"/ proc / selfリンクを印刷:"、readlink( "/ proc / self")、 "-pid $$ \ n";'

/ proc / selfはシンボリックリンクとして動作しますが、procfsファイルシステムにより「魔法のように」プロセスが認識されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.