1.実験テーマ
Linuxプロセス制御
2. 実験の目的
プロセスの作成・中止・操作を通じて、プロセスの概念やプロセスの同時実行について理解を深め、プロセスとプログラムの違いを明確にします。
3. 実験内容(実験原理・使用した理論知識、アルゴリズム・プログラムフローチャート、手順と方法、キーコード)
(1) タスク 1: プロセスの作成
タスク要件: システム コール fork() を使用して子プロセスを作成するプログラムを作成します。このプログラムを実行すると、システムは
には親プロセスと子プロセスのアクティビティがあります。各プロセスに画面上に文字を表示させます。親プロセスは文字「b」を表示します。
子プロセスには文字「a」が表示され、親プロセスと子プロセスの両方に文字「c」が表示されます。
ステップ 1: vi または gedit を使用して新しい fork_demo.c プログラムを作成し、リスト 3-1 のプログラムをコピーし、cc または
gcc は実行可能ファイル fork_demo をコンパイルします。たとえば、コンパイルは gcc –o fork_demo fork_demo.c で実行できます。
ステップ 2: コマンドラインに「./fork_demo」と入力してプログラムを実行します。
ステップ 3: プログラムを複数回実行し、画面上の表示結果を観察し、複数の実行で異なる結果が表示される理由を分析します。
(2) タスク 2: 子プロセスが新しいタスクを実行します
タスク要件: システム コール fork() を使用して子プロセスを作成するプログラムを作成します。子プロセスはシステムを通じて exec を呼び出します。
元の実行コードを置き換えて、Linux コマンド /bin/ls を実行し (現在のディレクトリのリストを表示)、exit() 関数を呼び出します。
数は終わりました。親プロセスは、waitpid() を呼び出して子プロセスの終了を待ち、子プロセスの終了後に子プロセスの識別子を表示します。
終わることも多い。プログラムの実行プロセスを図 3-1 に示します。
ステップ 1: vi または gedit を使用して新しい exec_demo.c プログラムを作成し、リスト 3-2 のプログラムをコピーします (プログラムの実行)
図 3-1 に示す行)、cc または gcc を使用して実行可能ファイル exec_demo をコンパイルします。たとえば、 gcc –o exec_demo を使用できます。
exec_demo.c でコンパイルが完了します。
ステップ 2: コマンドラインに「./exec_demo」と入力してプログラムを実行します。
ステップ 3: 画面上のプログラムの表示結果を観察および分析します。
図 3-1 exec_demo.c プログラムの実行プロセス
4. 実験結果と解析
実験 1:
このプログラムは、fork() 関数を呼び出して子プロセスを作成し、親プロセスと子プロセスでそれぞれ文字「a」と文字「b」を出力し、最後に両方のプロセスで文字「c」を出力します。
どのような出力であっても、複数プロセスの同時実行の特性に準拠します。
分析します:
srand((unsigned)time(NULL)) は、乱数発生器を初期化するために使用されます。
fork() 関数は、子プロセスを作成するために使用されます。親プロセスでは、fork() は子プロセスのプロセス ID を返し、子プロセスでは、fork() は 0 を返します。プロセスの作成に失敗した場合、fork() は -1 を返します。
sleep(rand() % 2) と sleep(rand() % 3) は、プロセスをランダムな時間待機させるために使用されます。
printf 関数は文字を出力するために使用されます。
親プロセスと子プロセスの両方が printf("c") の最後の行を実行します。
実験 2:
このプログラムは、fork() 関数を呼び出して子プロセスを作成し、その子プロセスで execlp("/bin/ls", "ls", NULL) コマンドを実行し、新しいプログラムをロードして実行します。最初の引数 file は、実行する実行可能ファイルへのパスです。この場合、/bin/ls は、実行される実行可能ファイルが /bin ディレクトリ内の ls プログラムであることを意味します。つまり、ls コマンドを呼び出して、現在のディレクトリ内のファイルとフォルダーを一覧表示します。2 番目のパラメータ「ls」は、実行中のプログラムの名前です。親プロセスは、子プロセスの実行が完了するまで待機し、「Child Complete」を出力します。
プログラムを実行すると、出力は次のようになります。
分析します:
fork() 関数は、子プロセスを作成するために使用されます。親プロセスでは、fork() は子プロセスのプロセス ID を返し、子プロセスでは、fork() は 0 を返します。プロセスの作成に失敗した場合、fork() は -1 を返します。
execlp("/bin/ls", "ls", NULL) は、子プロセスで ls コマンドを実行するために使用されます。
親プロセスは、wait(NULL) 関数を使用して子プロセスの実行が完了するのを待ち、子プロセスが完了する前に終了しないようにします。
子プロセスは、execlp() 関数を通じて ls コマンドを実行し、ls の出力を標準出力に出力します。
子プロセスの実行が終了すると、親プロセスは「Child Complete」を出力します。
5. まとめと経験
1. プロセスの作成: fork() 関数を使用して、親プロセスのコピーである新しい子プロセスを作成します。子プロセスは、fork() 関数が戻った場所から実行を開始し、親プロセスのコードの実行を継続したり、新しいタスクを実行したりできます。
2. 同時実行: マルチプロセス環境では、親プロセスと子プロセスは同時に実行でき、互いに独立して実行できます。オペレーティング システムは、プロセス スケジューリング アルゴリズムを通じてプロセスの実行順序とタイム スライスの割り当てを決定します。
3. ランダム性: 実験では、rand() 関数と srand() 関数を使用して乱数を生成し、ランダムな待機時間を通じてプロセスの不確実性と同時実行性をシミュレートします。このようにして、さまざまなプロセスの実行順序が異なる可能性があることがわかります。
4. サブプロセスの新しいタスク: リスト 2-2 は、サブプロセスが新しいタスクを実行する方法を示しています。execlp() 関数を呼び出すことにより、子プロセスは他の実行可能プログラムを実行してさまざまな機能を実現できます。親プロセスは、子プロセスが完了するのを待つことで、子プロセスの実行順序を調整できます。
5. 親プロセスと子プロセス間の通信: これら 2 つの実験では、親プロセスと子プロセスの間に直接的な通信はありません。これらは同時実行を実装し、オペレーティング システムのプロセス管理メカニズムを通じて子プロセスが完了するのを待ちます。
6. 実験結果の不確実性: プロセスのスケジュールとランダム性の影響により、実験結果には多くの可能性が含まれる可能性があります。同じプログラムが異なる出力を生成する場合がありますが、これはマルチプロセス環境の特徴です。