https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s3-proc-self.html 説明する
この
/proc/self/
ディレクトリは、現在実行中のプロセスへのリンクです。
常に同時に複数のプロセスが実行されていますが、「現在実行中のプロセス」とはどのようなプロセスですか?
コンテキスト切り替えを考慮すると、「現在実行中のプロセス」は現在CPUで実行されているプロセスに関連していますか?
「現在実行中のプロセス」は、フォアグラウンドおよびバックグラウンドプロセスとは独立していますか?
答え1
これはフォアグラウンドプロセスとバックグラウンドプロセスとは何の関係もありません。現在実行中のプロセスにのみ関連します。カーネルが/proc/self
「それが何を指しているのか」という質問に答えなければならないとき現在のスケジュールのPIDを選択してください。、つまり現在実行中のプロセス(現在の論理CPU上)。その効果は、/proc/self
実行している場合は常に要求するプログラムのpidを指すことです。
ls -l /proc/self
pidが表示され、ls
そのコードを使用するコードを作成すると、/proc/self
独自のpidなどが表示されます。
答え2
シンボリックリンクにアクセスします(readlink()を呼び出すか、それを通過するパスでopen()を呼び出す)。当時はCPU上で動作しますが、関係ありません。マルチプロセッサシステムは、CPUで複数のプロセスを同時に実行できます。
フォアグラウンドおよびバックグラウンドプロセスはデフォルトでシェル構成であり、システム内のすべてのシェルセッションに1つあるため、独自のフォアグラウンドプロセスはありません。
答え3
フレーズはより良かったかもしれませんが、自己参照的なアイデアを表現するために書くことを望むフレーズは混乱します。ディレクトリ名はもっと説明的だと思います。
デフォルトでは、/proc/self/
読み込みプロセスを表します/proc/self/
。したがって、/proc/self/
Cプログラムで開こうとすると、そのプログラムを表します。シェルでこれを行う場合は、シェルなどです。
しかし、マルチタスクの代わりに実際に4つのプロセスを同時に実行できるクアッドコアCPUがあるとしたらどうでしょうか。
これにより、各プロセスは/proc/self/
互いの現実を見ることができなくても、異なるバージョンの現実を見ることができます/proc/self/
。
どのように動作しますか?
まあ、/proc/self/
実際にはフォルダではありません。デバイスドライバであり、アクセスしようとするとフォルダの形で公開されます。フォルダに必要なAPIを実装するためです。ディレクトリ/proc/self/
だけがこれを行うわけではありません。リモートサーバーから共有フォルダをマウントするか、USBサムドライブまたはドロップボックスをマウントすることを検討してください。これらはすべて同じAPIセットを実装することで動作し、フォルダのように動作します。
プロセスがデバイスドライバにアクセスしようとすると、/proc/self/
デバイスドライバはプロセスからデータを読み取り、その内容を動的に生成します。したがって、内部ファイルは/proc/self/
実際には存在しません。それは観察しようとしているプロセスを再び反射する鏡のようです。
本当にデバイスドライバですか?あまりにも単純化されたようですね!
はい、確かです。賢くなりたいならカーネルモジュールがあります。しかし、さまざまなLinux開発者チャネルのUsenet投稿を見ると、ほとんどのカーネル開発者は「デバイスドライバ」と「カーネルモジュール」を同じ意味で使用します。私はLinux用のデバイスドライバ、つまりカーネルモジュールを書いていました。 Linuxで独自のインターフェースを作成したい場合は/proc/
、たとえば、このWebサイトの投稿を返すファイルシステムが必要な場合は、/proc/unix.stackexchange/
O'Reillyが発行した有名な「Linux Device Drivers」の本でこれを行う方法を学ぶことができます。オンラインでもソフトコピーで見ることができます。
答え4
/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 として解釈します。これは、ディレクトリの内容を読み取るプロセス(新しく作成された/ bin / lsプロセス)のPIDであるためです。ただし、パイプラインの次のプロセス(シェルスクリプトの場合)またはプロンプトが返された場合(対話型シェルの場合)パスはもう存在しません。情報出力は存在しないプロセスを意味します。
ただし、これは外部コマンド(シェル自体に組み込まれていない実際の実行可能プログラムファイル)でのみ機能します。したがって、パス名を外部プロセス/ bin / lsに渡すのではなく、ファイル名globbingを使用してディレクトリの内容のリストを取得すると、別の結果が得られます。
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()システムコールを介して新しいプロセス "/bin/ls"を作成し、 "/proc/self/fd"をargv [1]に渡します。 '/bin/ls' は、/proc/self/fd ディレクトリを順番に開き、繰り返し中にその内容を読み込み、印刷します。
しかし、2行目では、後で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/*のように動作します。