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データベースインデックスの欠点と適切な使用

推薦する

MySQL 8.0.23 のレプリケーション アーキテクチャにおけるスレーブ ノードの自動フェイルオーバー

私はしばらく MGR と連絡を取り合ってきました。MySQL 8.0.23 の登場により、MySQL...

CSS プロパティ display:flow-root 宣言を 1 つの記事でマスターする

zhangxinxu より https://www.zhangxinxu.com/wordpress...

Docker nginxは1つのホストを実装して複数のサイトを展開します

とあるサイトからレンタルした仮想マシンの有効期限が近づいており、更新料が200元以上かかります。Al...

一般的なDocker Composeコマンドの詳細な説明

1. Docker Compose の使用方法は docker コマンドの使用方法と非常に似ています...

Dockerコンテナを終了した後も実行を継続する方法

現象:イメージを実行します (例: ubuntu14.04)。 docker run -it --r...

MySQL 5.7 における基本的な JSON 操作ガイド

序文プロジェクトのニーズにより、ストレージ フィールドは JSON 形式で保存されます。プロジェクト...

大きなオフセットによる MySQL 制限ページングが遅い理由と最適化ソリューション

MySQL では通常、limit を使用してページ上のページング機能を完了しますが、データ量が大きな...

MySQL でよく使われる連結文のまとめ

はじめに: MySQL では、CONCAT() 関数を使用して複数の文字列を 1 つの文字列に連結し...

JavaScriptプロトタイプとプロトタイプチェーンを徹底的に理解する

目次序文基礎を築くプロトタイプコンストラクタのプロパティ__プロト__プロトタイプチェーン改善する要...

VMware WorkStation を Docker for Windows で使用するための詳細なチュートリアル

目次1. はじめに2. Windows用Dockerをインストールする1. Windows用Dock...

PostgreSQL正規表現の一般的な機能の概要

PostgreSQL正規表現の一般的な機能の概要正規表現は、複雑なデータ処理を必要とするプログラムに...

太字の <b> と <strong> の違いの分析

私たちウェブマスターは皆、ウェブサイトを最適化する際に記事内のキーワードを太字にすることが最適化に非...

ウェブデザインの教育または学習プログラム

セクションコース内容営業時間1 ウェブデザインの概要2 2 HTML 基本タグとフォーマットタグ 2...

MySQLストレージフィールドタイプのクエリ効率についての簡単な理解

検索パフォーマンスは最速から最遅まで次のとおりです (私が聞いたところによると)。 1 番目: ti...

Tomcat を使用して IntelliJ IDEA によってデプロイされたプロジェクトの場所はどこですか?

IntelliJ IDEA が Tomcat を使用して Javaweb プロジェクトをデプロイし...