Linux 環境変数とプロセス アドレス空間の概要

Linux 環境変数とプロセス アドレス空間の概要

Linux 環境変数とプロセスアドレス空間

// プロセス pid と親プロセスを表示します [dy@VM-12-10-centos jincheng_12_5]$ ps ajx | head -1 && ps axj | grep 3669470
   PPID PID PGID SID TTY TPGID STAT UID 時間 コマンド
3669469 3669470 3669470 3669439 ポイント/0 3681645 S 1001 0:00 -bash
3669470 3681645 3681645 3669439 ポイント/0 3681645 R+ 1001 0:00 ps axj
3669470 3681646 3681645 3669439 ポイント/0 3681645 R+ 1001 0:00 grep --color=auto 3669470


//パスを追加せずにプログラムを実行する最初の方法 [dy@VM-12-10-centos jincheng_12_5]$ ll
合計 28
-rw-rw-r-- 1 dy dy 73 12月 5 16:46 Makefile
-rwxrwxr-x 1 dy dy 17432 12月5日 16:47 proc
-rw-rw-r-- 1 dy dy 75 12月 5日 16:47 proc.c
[dy@VM-12-10-centos jincheng_12_5]$ sudo cp proc /usr/bin/                  
// システム パスに独自の実行可能プログラムを追加します [sudo] dy のパスワード: 
[dy@VM-12-10-centos jincheng_12_5]$ proc // システム パスに独自の実行可能プログラムを追加します。./ パスを追加する必要はありません。Hello world!
[dy@VM-12-10-centos jincheng_12_5]$ ./proc
こんにちは世界!
[dy@VM-12-10-centos jincheng_12_5]$ sudo rm /usr/bin/proc //システムパスから削除 [dy@VM-12-10-centos jincheng_12_5]$ proc
-bash: /usr/bin/proc: そのようなファイルまたはディレクトリはありません

//2番目のタイプ [dy@VM-12-10-centos jincheng_12_5]$ $PATH
-bash: /home/dy/.local/bin:/home/dy/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin: そのようなファイルまたはディレクトリはありません
[dy@VM-12-10-centos jincheng_12_5]$パスワード
/ホーム/dy/金城_12_5
//環境変数 PATH に現在のパスを追加します [dy@VM-12-10-centos jincheng_12_5]$ PATH=$PATH:/home/dy/jincheng_12_5
[dy@VM-12-10-centos jincheng_12_5]$ プロシージャ
こんにちは世界!

//3000コマンドのみ保存 [dy@VM-12-10-centos jincheng_12_5]$ echo $HISTSIZE
3000
// [dy@VM-12-10-centos jincheng_12_5]$ history |wc -l 以前に実行されたコマンドの数を表示します
636
[dy@VM-12-10-centos jincheng_12_5]$ 履歴
// 以前のコマンドをすべてディスプレイに出力します // すべての環境変数を表示します [dy@VM-12-10-centos jincheng_12_5]$ env
LS_COLORS = RS = 0:DI = 01; 34:LN = 01; 36; 36:MH = 00:PI = 40; 33:SO = 01; 35:DO = 01; 35:BD = 40; 33; 01:CD = 40; 33; 01:OR = 40; 31; 01 ; 41:TW = 30; 42:OW = 34; 42:st = 37; 44:ex = 01; 32:*。tar = 01; 31:*。tgz= 01; 31:*。arc = 0 01; 31:*。tlz = 01; 31:*。txz = 01; 31; 31:*。tzo= 01; 31:*。t7z = 01; 31:*。zip = 01; 31:*。z = 01; 31:*。dz = 01; 31:*。gz= 01; 31:*。 XZ = 01; 31:*。ZST = 01; 31:*。TZST= 01; 31:*。BZ2= 01; 31:*。BZ= 01; 31:*。TBZ = 01; 31:***。 ear = 01; 31:*。sar = 01; 31:*。rar = 01; 31:*。alz = 01; 31:*。ace = 01; 31:*。動物= 01; 31:*。cpi​​o = 01; 31:* 01; 31:*。esd = 01; 31:*。jpg = 01; 35:*。jpeg= 01; 35:*。mjpg = 01; 35:*。mjpeg = 01; 35:*。gif = 01; 35:*。bmp = 01; 35:* :*。tga = 01; 35:*。xbm = 01; 35:*。xpm= 01; 35:*。tif = 01; 35:*。tiff= 01; 35:*。png = 01; 35:*。svg = 01; 35:*。svg = 01; mng = 01; 35:* = 01; 35:*。mpg = 01; 35:*。mpeg = 01; 35:*。m2v = 01; 35:*。mkv = 01; 35:*。webm = 01; 35:*。ogm = 01; 35:*。mp4 = 01; 35:* 35:*。Qt = 01; 35:*。nuv = 01; 35:*。wmv= 01; 35:*。asf = 01; 35:*。rm = 01; 35:*。rmvb = 01; 35:*。flc = 01; 35:* ; 35:*。dl = 01; 35:*。xcf = 01; 35:*。xwd= 01; 35:*。yuv = 01; 35:*。cgm = 01; 35:*。emf = 01; 35:*。ogv = 01; 35:* flac = 01; 36:*。M4a= 01; 36:*。Mid = 01; 36:*。Midi= 01; 36:*。MP3= 01; 36:*。M:*。OGG = 01; 36:* 01; 36:*。XSPF = 01; 36:
LANG=en_US.utf8
履歴時間フォーマット=%F %T 
ホスト名=VM-12-10-centos
OLDPWD=/home/dy
ユーザー=dy
PWD=/home/dy/jincheng_12_5
ホーム=/ホーム/dy
メール=/var/spool/mail/dy
シェル=/bin/bash
TERM=xterm
SHLVL=1
PROMPT_COMMAND=history -a; history -a; printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"
ログ名=dy
PATH=/home/dy/.local/bin:/home/dy/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dy/jincheng_12_5
ヒストサイズ=3000
LESSOPEN=||/usr/bin/lesspipe.sh %s
_=/usr/bin/env


echo: 環境変数の値を表示する

エクスポート: 新しい環境変数を設定する

[dy@VM-12-10-centos jincheng_12_5]$ ./proc //ローカル変数は存在しません 私は proc です: pid:3700079 ppid:3669470
セグメンテーション違反(コアダンプ)
[dy@VM-12-10-centos jincheng_12_5]$ MY_VALをエクスポートします
[dy@VM-12-10-centos jincheng_12_5]$ ./proc
私はプロセスです: pid:3700163 ppid:3669470
こんにちは、ディ
/home/dy/.local/bin:/home/dy/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dy/jincheng_12_5
/ホーム/dy
バイナリ

env: すべての環境変数を表示する

設定解除: 環境変数をクリアする

env 環境変数

set: ローカルに定義されたシェル変数と環境変数を表示する

//環境変数を設定する [dy@VM-12-10-centos jincheng_12_5]$ hello=1234
//出力環境変数に $ を追加することを忘れないでください [dy@VM-12-10-centos jincheng_12_5]$ echo $hello
1234
[dy@VM-12-10-centos jincheng_12_5]$ set | grep hello
こんにちは=1234

コマンドラインで実行されるコマンドのほとんどは、親プロセスとして bash を持ちます。bash は、コマンドを実行する子プロセスを作成します。

コードを通じて環境変数を取得する

#include <stdio.h>
#include<stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[], char *env[])
{
        for(int i = 0; argv[i]; ++i)//コマンドラインパラメータを解釈する//for(int i = 0; i < argc; ++i)
        {
            printf("argv[%d]:%s\n",i,argv[i]);
        }
        for(int i = 0; env[i]; ++i) //環境変数は次のコードで取得できます {
           printf("env[%d]:%s\n",i,env[i]);
        }
   0を返します。
}

[外部リンク画像の転送に失敗しました。ソースサイトにはアンチホットリンクメカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-7v2pxCt8-1639035758639)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211208141656121.png)]

int x = atoi(argv[2]);
int y = atoi(argv[3]);
(strcmp(argv[1],"-a") == 0の場合)
{
    printf("%d + %d = %d\n",x,y,x+y);
}
それ以外
{
    printf("%d - %d = %d\n",x,y,xy);
}

ここに画像の説明を挿入

各プログラムは環境テーブルを受け取ります。環境テーブルは文字ポインターの配列であり、各文字ポインターは '\0' で終わる環境文字列を指します。

ここに画像の説明を挿入

サードパーティの変数environを通じて環境を取得することもできます。

#include <stdio.h>
int main(int argc, char *argv[])
{
    外部char **environ;
    整数 i = 0;
    for(; 環境[i]; i++){
    	printf("%s\n", 環境[i]);
    }
	0を返します。
}

ここに画像の説明を挿入

プロセスアドレス空間

#include <stdio.h>
#include <unistd.h>
g_val = 0;
int メイン()
{
   pid_t id = fork();
   id < 0の場合
   {
       perror("fork() 失敗\n");
   }
   そうでない場合(id == 0)
   {
       printf("私は子供です:%d,%d,%p\n",getpid(),g_val,&g_val);
   }それ以外
   {
       printf("私は太った人です: %d, %d, %p\n",getppid(),g_val,&g_val);
   }
   0を返します。
}

ここに画像の説明を挿入

実行結果から、2 つのプロセスの変数の値とアドレスが同じであることがわかります。ここではコードに変更は加えられていません。子プロセスは親プロセスをテンプレートとして使用するため、アドレスは同じです。

コードを少し変更してみましょう

#include <stdio.h>
#include <unistd.h>
g_val の整数値。
int メイン()
{
   pid_t id = fork();
   id < 0の場合
   {
       perror("fork() 失敗");
   }
   そうでない場合(id == 0)
   {
       100 を返します。
       printf("私は子供です:%d,%d,%p\n",getpid(),g_val,&g_val);
   }それ以外
   {
       睡眠(3);
       printf("私は太っちょです: %d, %d, %p\n",getppid(),g_val,&g_val);
   }
   0を返します。
}

ここに画像の説明を挿入

この時点で、変数の値は変更されており、親プロセスは 0、子プロセスは 100 ですが、変数のアドレスは同じままであることがわかります。

この実行結果から、以下の点がわかります。

2 つのプロセスの変数の値は異なるため、親プロセスと子プロセスの変数は間違いなく同じ変数アドレス値ではなく、間違いなく物理アドレスでもありません。 ! !私たちが目にするアドレスはすべて仮想アドレスです。 ! !実際の物理アドレスはユーザーには見えず、OS によって管理されます (OS は仮想アドレスを物理アドレスに変換する役割を担います)。コードは共有されますが、それぞれがデータの独自のプライベート コピーを持ちます (コピーオンライト)。

なぜ物理アドレスではなく仮想アドレスなのでしょうか?

プロセスアドレス空間とは何ですか?

プロセスアドレス空間: メモリを見る方法、抽象的な概念、カーネル構造体 mm 構造体なので、各プロセスは排他的なシステムメモリリソースを持っていると考えます (父親の財産は自分だけのものだと考えます) 領域分割: アドレス空間は線形であり、[開始、終了] という領域に次々に分割されます 仮想アドレス: [開始、終了] 間の各アドレスは仮想アドレスと呼ばれます

ここに画像の説明を挿入

仮想アドレスと物理アドレスのマッピング

ここに画像の説明を挿入

プロセス アドレス空間はなぜ存在するのでしょうか?

物理メモリを保護し、プロセス内のアドレスへの直接アクセスを防止することで、正当性の検証が容易になります。メモリ管理をプロセス管理から分離することで、各プロセスがコードとデータを同じように表示できるようになります。

[外部リンク画像の転送に失敗しました。ソースサイトにはアンチホットリンクメカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-wu0C4V57-1639035758649) (C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211209150456785.png)]

これからは、プロセスとプログラムの違いを直接見分けることができます。

ここに画像の説明を挿入

Linux 環境変数とプロセス アドレス空間に関するこの記事はこれで終わりです。Linux 環境変数とプロセス空間に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Linux環境で環境変数を設定する方法
  • Linux環境変数ファイルの簡単な紹介
  • Linuxの運用と保守、基本的なプロセス管理、リアルタイム監視と制御

<<:  初心者向けBootstrap 3.0学習ノート

>>:  MySQLデータベースインデックスの欠点と適切な使用

推薦する

Element-ui アップロードファイルのアップロード制限の解決策

質問アップロードするファイルのタイプを accept に追加することは、「表面的な」役割しか果たしま...

MySQL 8.0.23 メジャーアップデート (新機能)

著者: Guan Changlong は、Aikesheng の配送サービス部門の DBA です。主...

ReactとAntdのFormコンポーネントを組み合わせてログイン機能を実装する方法を詳しく説明します

目次1. ReactとAntdを組み合わせてログイン機能を実現2. ReactとAntdを組み合わせ...

html2canvas を使用して、Baidu マップを含む Dom 要素を画像に処理するソリューション

問題 1: Baidu Map はタイル画像 (地図が写真で構成されている) を使用しています。ht...

React双方向データバインディングの原理についての簡単な説明

目次双方向データバインディングとは双方向データバインディングの実装データ影響ビュービューはデータに影...

Linuxはシェルスクリプトを使用して履歴ログファイルを定期的に削除します

1. ツールディレクトリのファイル構造 [root@www tools]# ツリーツール/ ツール/...

MySQL列挙型のテスト例

プロジェクトを開発しているとき、支払い済み、支払済み、クローズ済み、返金済みなどの注文ステータスなど...

Mysqlは隣接リスト(隣接リスト)を通じてツリー構造を保存します。

以下の内容では、隣接リストを使用してツリー構造を保存する MYSQL のプロセスとソリューションを紹...

Navicat for MySQL 15 登録とアクティベーションの詳細なチュートリアル

1. Navicat for MySQL 15をダウンロードするhttps://www.navica...

Three.js が Facebook Metaverse 3D ダイナミック ロゴ効果を実現

目次背景メタバースとは何ですか?成果を達成するトライアル 1: THREE.TorusGeometr...

jsは配列の平坦化を実装します

目次配列をフラット化する方法1.flat() の使用2. 正規表現を使用する3.reduce()+c...

Vue3+TypeScriptはaxiosをカプセル化し、リクエスト呼び出しを実装します

まさか、2021年になってもTypeScriptについて聞いたことがない人がいるなんて?プロジェクト...

バージョン管理ツール Rational ClearCase の紹介

Rational ClearCase は、コードやその他のソフトウェア開発資産のバージョン管理を実...

Reactにおけるフックの一般的な使用法

目次1. フックとは何ですか? 2. フックはなぜ現れるのでしょうか? 3. よく使われるフックは何...

CSS における重要なカスケード概念の詳細な説明

最近、プロジェクトの過程で問題に遭遇しました。メニューバーを常に上部に表示し、後続の要素をその下に表...