ネットワーク・プログラミング デバイスドライバと環境変数
全体の位置づけ オペレーションシステム(Linux) ソケットプログラミング プロセス カーネルとシステムコール プロセス間通信 スレッド クライアントーサーバ 非同期I/Oとマルチタスク
1.1 デバイスドライバとモジュール Linux OS デバイスドライバ モジュール 1.1 デバイスドライバとモジュール Linux OS デバイスドライバ ハードディスク、キーボード等のキャラクタデバイスをアクセスするためのソフトウェア。 モジュール 高機能ハードウェア(ビットマップディスプレイ、ネットワーク)をアクセスするためのソフトウェア。 カーネルと独立した設計、実装単位。 汎用性の高いモジュールインタフェース。 カーネル モジュール インタフェース デバイスドライバ インタフェース モジュール デバイス ドライバ イーサネットボード ハードディスク
1.2 システムコール時のモード切替 CPUのモード切替 trap命令 プロセス実行時はユーザモード。 カーネル実行時はカーネルモード。 1.2 システムコール時のモード切替 実行中のプログラム CPUのモード切替 プロセス実行時はユーザモード。 カーネル実行時はカーネルモード。 trap命令 アセンブリ言語の命令。 CPUをカーネルモードに切替え、指定したアドレスにあるカーネル関数を実行させる命令。 モード ① : trap s 分岐テーブル ② ③ システムコール ポインタ変数の配列 関数 ユーザ空間 カーネル空間 ① CPUをカーネルモードに切替 ② カーネル空間内の分岐テーブル参照 ③ カーネル関数を実行
topやpsコマンドでプロセスを一覧出来る 1.3 カーネルの開始 ハードディスク内のカーネルがメモリ上にロードされる。 gettyプログラム ユーザがログイン出来るように、ユーザIDとパスワードの入力を受付ける。 ログインが成功すると、指定されたシェルプログラムを実行する。 デーモン(メモリ常駐プロセス) ネットワーク(inetd) システムログ(syslogd) 定期的に起動するプログラム(crond) カーネルは、ハードとソフト(割込処理、スケジューラ、クロック、モジュール)を初期化する。 initプロセス(プロセスid=1)がデーモン、getty等のプロセスを生成する。 w: 現在ログイン中のユーザ表示 last: 最近ログインしたユーザ表示 history: 過去に実行したコマンド topやpsコマンドでプロセスを一覧出来る
プロセスの生成とコマンドの実行 2.1 環境変数の利用 プロセスの生成とコマンドの実行 2.1 環境変数の利用 子は親の完全なコピー 子プロセス のメモリ空間 newenv.c 親プロセス (シェル) fork(); path argv[0] argv[1] envp[0] envp[1] . execl (/home/oida/newenv, newenv,envp); #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[], char *envp[]) { int i; for (i=0;envp[i]!=NULL;i++) { printf(“%s\n”,envp[i]); } return EXIT_SUCCESS; n e w e n v \0 n e w e n v \0 NULL P A T H = / u envp配列も親からコピーされる S H E L L = / % ./newenv PWD=/home/oida/ USER=oida … 環境変数の一覧が表示される % path argv[0] ハードディスク / execlにより、ハードディスクからnewenvを取ってきて子プロセスのメモリ上にロードする。 home usr newenv
2.2 プロセスの状態 ゾンビ状態 プロセスの状態 プロセス自体は消滅しているが、プロセステーブルが開放されていない状態。 2.2 プロセスの状態 ゾンビ状態 プロセス自体は消滅しているが、プロセステーブルが開放されていない状態。 子プロセスは実行終了後、親プロセスに終了したことを通知するシグナルを送った後、ゾンビ状態になる。 親プロセスがwaitシステムコールを実行すると、子プロセスはプロセステーブルから削除される。 zombie.c int main() { int i; if (fork()==0) { exit(EXIT_FAILURE); } else { sleep(300); wait(&i); printf(“return code=%d\n”, WEXITSTATUS(i)); } return EXIT_SUCCESS; 子プロセスの実行結果(EXIT_FAILURE)を表示する ユーザモード 実行中 % ./zombie & % ps l F UID PID … 000 1000 … ./zombie 044 1000 … [zombie <defunct>] … % return code=1 +Done ./zombie システムコールや割込みにより状態が遷移する。 カーネルモード 実行中 ゾンビ状態 消滅したという意味の英語 スリープ状態 実行可能状態 プロセスの状態
宿題4 elapse_time.c 宿題: elapse_time.cを参考にして、子プロセスの実行時間を測定するプログラム(hw4.c)を作成せよ。 尚、子プロセスは5秒間sleep後、exitする。 表紙に氏名と学籍番号を書く 本文にプログラムを書く プログラムの実行結果を書く 実施した内容を説明する文章を書く レポートの締切は次の週の水曜日18:00 #include <stdio.h> #include <stdlib.h> time_t start, end; int main() { time(&start); // start sleep(5); time(&end); // stop printf("elapsed time= %d seconds\n", end-start); return EXIT_SUCCESS; } [oida@rpc261 soft2]$ gcc elapse_time.c -o elapse_time [oida@rpc261 soft2]$ ./elapse_time elapsed time= 5 seconds [oida@rpc261 soft2]$
宿題4のヒント 親 子 time() fork() sleep(5) wait() exit() time() hw4.c #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> time_t start, end; int main() { int j; time(&start); // start if (fork()==0) { } wait(&j); time(&end); // stop printf("elapsed time= %d seconds\n", (int) (end-start)); return EXIT_SUCCESS; 親 子 time() fork() sleep(5) wait() time() exit() この部分に、5秒間スリープ後、exit()するプログラムを書く。 2行です。子プロセスの実行結果(EXIT_SUCCESS)も忘れずに入れる。