[LINUX-04] Linuxプロセス、スケジューリング、スレッド、プロセスコンテキスト、およびその他の理解

1.シグナルはプロセスまたはカーネルから送信されます
。2。コード空間とデータ空間(グローバル変数または静的変数)、ファイル記述子、シグナル、およびスレッドによって共有されるmallocによって割り当てられたメモリ。各スレッドには、独立したスタック空間とプログラムカウンターがあります。スレッドを作成するとき、pthread_create関数を呼び出すスレッドと新しく作成されたスレッドの実行順序はランダムです

3. Linuxでは、軽量プロセスを使用してスレッドをシミュレートし、スレッド操作の関連機能をサードパーティのスレッドライブラリ(LinuxthreadsまたはネイティブPOSIXスレッドライブラリ(NPTL))を介して実装します。

4. down()/ down_interruptible()はカーネルスペースの実行ユニットを同期するために使用され、down(struct semaphore * sem)はセマフォsemを取得するために使用されます。呼び出し元がセマフォを取得できない場合、スリープ状態になり、スリープ状態に入りますシグナルによってプロセスを中断することはできません。down_interruptibleが原因でスリープ状態になったプロセスがシグナルによって中断され、関数が復帰する可能性があります。

5.タイムスライス:プロセスが実行状態にあるときに残っているクロックティックの数この値は、クロック割り込みが到着するたびに1ずつ減少します。このフィールドの値が0になるまで次第に小さくなると、need_reschedフィールドは1に設定されます(スケジューリング時間になると、このフィールドの値を確認し、1の場合は、schedule()を呼び出します)。

6. OSクロック(ティッククロック)は、Linuxシステムスケジューリングの基準クロックとして使用されます。

7. Linuxマルチスレッドプログラミングでは、sleep関数を使用してスレッドのCPU制御を解放できますテストコードは次のとおりです

#include <stdio.h> 
#include <unistd.h> 
#include < string .h> 
#include <pthread.h>


void * SleepTest1(void * arg)
{
        ながら1 
        {
                printf(" sleeptest1は大丈夫です!\ n " );
                スリープ(3 );
        }
}


void * SleepTest2(void * arg)
{
        ながら1 
        {
                printf(" sleeptest2は大丈夫です!\ n " );
                スリープ(10 );
        }
}

int main(int argc、char * argv [])
{
        pthread_t tid [ 2 ];
        int ret;
        ret = pthread_create(&tid [ 0 ]、NULL、SleepTest1、NULL);
        if(ret < 0 
        {
                printf(" pthread_create " );
                リターン - 1 
        }
        ret = pthread_create(&tid [ 1 ]、NULL、SleepTest2、NULL);
        if(ret < 0 
        {
                perror(" pthread_create " );
                リターン - 1 
        }
        printf(" thread1およびthread2 create ok!\ n " );

        pthread_join(tid [ 0 ]、NULL);
        pthread_join(tid [ 1 ]、NULL);
        printf(" スレッド出口!\ n " );

         0を返します
}

 

8.ゾンビプロセス:各プロセスが終了すると、カーネルはプロセスのすべてのリソース(開いているファイル、占有メモリなどを含む)を解放しますが、特定の情報(プロセス番号、終了ステータス、実行時間など)は保持しますなど)親プロセスが外部のwait / waitpidによってフェッチされるまで。この時点で、プロセスはデッドステートです。

 

9.プロセス終了

プロセスが終了すると、プロセスはそれが持っているリソースを解放し、何らかの方法で親プロセスに通知する必要があります(SIGCHLDシグナルを送信します)。プロセスの終了は通常、eixt()を表示または暗黙的に呼び出すか、何らかのシグナルを受け入れることです。しかし、何らかの理由で終了するため、最終的にdo_exitが呼び出されました。

 

プロセスの終了には2つのexitおよびexit_groupシステムコールがあり、exitは特定のプロセスを終了するだけで、exit_groupプロセスはスレッド全体で終了します。カーネルのサービス関数はsys_exitとsys_exit_groupで、それぞれdo_exitとdo_group_exitを呼び出します。そして、do_groupは最後にdo_exitを呼び出します(do_exitはkernel / exit.cで定義されています)。

 

10.プロセスによって開かれたファイル記述子を表示する

[root @ localhost proc] #cd 1328 /
[root @ localhost 1328]
#ls attr clear_refs cpuset exe io loginuid mountinfo net pagemap sched smaps statm task
auxv cmdline cwd fd delay maps mounts oom_adj personality schedstat stack status wchan
cgroup coredump_filter memiron fd mountstats oom_score root sessionid stat syscall
[root @ localhost 1328]#cd fdinfo /
[root @ localhost fdinfo]#ls
0 1 10 11 12 13 14 15 16 17 18 19 2 20 21 22 23 3 4 5 6 7 8 9
[root @localhost fdinfo]# 

fdinfoフォルダーにリストされている番号は、プロセスによって開かれたファイル記述子です

11.フォーク機能

フォークがコピーされるとき、親シーケンスによって実行されるコードは、冷却された状態で実行されるべきではありません!

12.プロセスコンテキストと割り込みコンテキストの詳細な説明

ユーザー空間のアプリケーションプログラムは、システムコールを通じてカーネル空間に入ります。このとき、ユーザー空間プロセスは多くの変数とパラメーター値をカーネルに渡す必要があり、カーネルモードの実行中は、ユーザープロセスのいくつかのレジスター値と変数を保存する必要もあります。いわゆる「プロセスコンテキスト」は、ユーザープロセスによってカーネルに渡されるこれらのパラメーター、およびカーネルと環境によってその時点で保存される変数とレジスター値のセットと見なすことができます

ハードウェアは、トリガー信号を介して、カーネルに割り込みハンドラーを呼び出し、カーネルスペースに入ります。このプロセス中に、ハードウェアの一部の変数とパラメーターもカーネルに渡され、カーネルはこれらのパラメーターを使用して割り込み処理を実行します。いわゆる「割り込みコンテキスト」は、ハードウェアおよびカーネルが保存する必要がある他のいくつかの環境(主に、現在中断されているプロセス環境)によって渡されるこれらのパラメーターと実際に見なすことができます

[簡単な理解:デバイスの動作中、実行される可能性のあるソフトウェアの2つの部分、つまりユーザープログラムとシステムカーネルがあります。アプリケーションが実行されると、カーネルはioctlなどの関数を介してアクセスできます。カーネルがこのアクセスを受信すると、CPUはカーネルの対応する関数コードセグメントを実行します。この時点で、現在の環境情報を保存して、実行後にカーネルコードが対応するアプリケーションコードセグメントに戻るようにします。これはプロセスコンテキストです。割り込みコンテキストでは、カーネルのみが割り込み処理を実行します。これは、シングルチップの割り込みの性質と同じです]

LINUXのコメント全体の段落:

プロセスの実行中、CPUのすべてのレジスタの値、プロセスの状態、およびスタックの内容は、プロセスのコンテキストと呼ばれます。カーネルが別のプロセスに切り替える必要がある場合、現在のプロセスのすべての状態、つまり現在のプロセスのコンテキストを保存する必要があるため、プロセスを再度実行すると、切り替え時の状態を実行する必要があります。Linuxでは、現在のプロセスコンテキストはプロセスのタスクデータ構造に格納されます。割り込みが発生すると、カーネルは、割り込みを受けたプロセスのコンテキストで、カーネル状態の割り込みサービスルーチンを実行します。ただし、同時に、必要なすべてのリソースが予約されるため、リレーサービスが終了したときに、中断されたプロセスの実行を再開できます。

プロセスコンテキストは、カーネルが配置されている動作モードであり、現時点では、システムコールの実行やカーネルスレッドの実行など、プロセスに代わってカーネルが実行されます。
コンテキスト:コンテキストはプロセスに関連する単なる環境であり、プロセスが実行されるときの環境です。具体的には、すべてのレジスタ変数、プロセスによって開かれたファイル、メモリ情報など、各変数とデータです。
    プロセスのコンテキストは、ユーザーレベルのコンテキスト、レジスタコンテキスト、およびシステムレベルのコンテキストの3つの部分に分けることができます。
    ユーザーレベルのコンテキスト:テキスト、データ、ユーザースタック、および共有ストレージ領域;
    レジスターコンテキスト:汎用レジスター、プログラムレジスター(IP)、プロセッサーステータスレジスター(EFLAGS)、スタックポインター(ESP);
    システムレベルのコンテキスト:プロセス制御ブロックtask_struct、メモリ管理情報(mm_struct、vm_area_struct、pgd、pte)、カーネルスタック。

    以下の場合には、プロセススケジューリング、切り替えのプロセスは、コンテキスト切り替え(コンテキスト・スイッチ)。オペレーティングシステムは、上述したすべての情報に切り替える必要が行われ、新たなスケジューリング処理を実行します。そしてシステムコールによるモード切替(モード切替)。プロセス切り替えと比較すると、モード切り替えの主なタスクはプロセスレジスタのコンテキスト切り替えることなので、モード切り替えははるかに簡単で時間を節約できます。 

13.プロセスの終了

Linuxでは、プロセスの終了は、正常終了と異常終了に分けられます。

1>正常に終了します

a。main()関数でreturnを実行します。

b。exit()関数を呼び出す

c。_exit()関数を呼び出す

2>異常終了

a。アボート関数を呼び出す

b。プロセスがシグナルを受け取り、そのシグナルがプログラムを終了させます。

exitメソッドに関係なく、システムは最終的に同じコードをカーネルで実行します。このコードは、プロセスによって使用されている開かれたファイル記述子を閉じ、メモリとプロセスが占有している他のリソースを解放するために使用されます。

3> _exit()とexit()の違い:

a._exit()は実行直後にカーネルに戻り、exit()は最初にクリーンアップ操作を実行してから、カーネルに制御を与える必要があります。

b。exit()と_exit()の違いの1つ:前者は、ユーザー定義の消去プログラムの呼び出し(atexit関数の登録)をサポートしています

c。_exit関数を呼び出すと、プロセスのすべてのファイル記述子が閉じられ、メモリと他のいくつかのカーネルクリーンアップ関数がクリーンアップされますが、フラッシュはしません

新しいストリーム(stdin、stdout、stderr ...)。exit関数は_exit関数のラッパーであり、_exitおよび

呼び出す前にストリームを更新します。

 

14.コピーオンライト技術

フォークは呼び出しプロセスのすべてのコンテンツをそのまま新しく作成された子プロセスにコピーします。これらのコピーアクションは非常に時間がかかります。フォークが完了した直後にexecを呼び出すと、これらのハードワークコピーすぐに消去されます。これは非常に費用効果が高いようです。そのため、フォークはすぐに親プロセスの内容をコピーしないように、「コピーオンライト」テクノロジーを設計しました。これは使用時にのみコピーされるため、次のステートメントがexecである場合、それは役に立たず、効率が向上します。

15.バックグラウンドプログラムを実行するときに注意すべき点いくつかあります。

ジョブをバックグラウンドで実行するときは注意してください。ユーザーの操作が必要なコマンドはバックグラウンドで実行しないでください。マシンがそこで待機するのがおかしいからです。ただし、ジョブをバックグラウンドで実行すると、結果が画面に出力され、作業が妨げられます。バックグラウンドで実行中のジョブが大量の出力を生成する場合、次の方法を使用して、その出力をファイルにリダイレクトするのが最善です
。command> out.file 2>&1&

16、フラッシュ機能

標準Cのfflush()は、出力バッファーのフラッシュをサポートしますが、入力バッファーの定義はありません

おすすめ

転載: www.cnblogs.com/Ph-one/p/12720452.html