実験プロセス作成
1. 実験の目的
- プロセスの概念の理解を深め、並行実行の本質をさらに理解する
- Linux オペレーティング システムのプロセスの作成および終了操作をマスターする
- Linux システムで子プロセスを作成し、新しいイメージをロードする操作をマスターします。
2. 実験内容
(1) C プログラムを作成し、システムコール fork( ) を使用して子プロセスを作成します。要件: ① 子プロセスで、現在のプロセスが子プロセスであることを示すプロンプト、現在のプロセスの PID と親プロセスの PID を出力し、ユーザーの入力に従って現在のプロセスの戻り値を決定し、プロンプトを終了します。 . ②親プロセスでは、現在のプロセスが親プロセスであることのプロンプト、現在のプロセスのPIDと子プロセスのPID、子プロセスの終了を待って得られた戻り値、および終了プロンプトを出力する。
(2) C プログラムを作成し、システム コール fork() を使用して子プロセスを作成し、子プロセスが exec ファミリ関数を呼び出してシステム コマンド ls を実行します。
3. 実験手順
1. 最初の実験の書き込みプロセス。vim を使用してコードを編集し、実行します。
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<errno.h>
#include<sys/wait.h>
#include<stdio.h>
int main(){
pid_t childpid; /*variable to store the child's pid*/
int retval; /*user-provided return code for child process*/
int status; /*child's exit status for parent process*/
/*create new process*/
childpid = fork()
if (childpid >= 0) {
if (childpid == 0) {
printf("Child:I am the child process\n");
printf("Child:My PID is %d\n",getpid());
printf("Child:My parent's PID is %d\n",getppid());
printf("Child:The value of fork return is %d\n",childpid);
printf("Child:Sleep for one second...\n");
sleep(1);
printf("Child:Enter an exit value (0~255): ");
scanf("%d",&retval);
printf("Child:Goodbye! \n");
exit(retval); /*child exits with user-provided return code*/
}
else {
printf("Parent:I am the parent process!\n");
printf("Parent:My PID is %d\n",getpid());
printf("Parent:The value of my child's PID is %d\n", childpid);
printf("Parent:I will now wait for my child to exit.\n");
wait(&status);
printf("Parent:Child's exit code is %d\n",WEXITSTATUS(status));
printf("Parent:Goodbye!\n");
exit(0);
}
}
else {
perror("fork error\n");
exit(0);
}
return 0;
}
2. 実験 2 のコード
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<errno.h>
#include<stdio.h>
#include<stdlib.h>
int main() {
int rtn; /*the return value of the son process*/
if (fork() == 0) {
/*The son process execution this process */
execlp("/bin/ls","ls -al",(char *)0);
exit(21); /*If the exec function return it's program,
that indicate it didn't exec the order normally,
so it must print the failure information*/
}
else {
/*the father process, is waiting the end of the son process and print the return value of the son process*/
wait(&rtn);
printf("child process return %d\n", rtn);
}
return 0;
}
4. 実験結果
実験 1 の実行結果:
実験2の実行結果
5. 実験のまとめと考え方
(1) fork()関数を呼び出したときの3つのリターン状況をまとめると、
fork関数の戻り値が0未満の場合は、子プロセスが正常に作成されていないことを意味します。元のプロセスはまだ実行中です.
fork 関数の戻り値が 0 の場合, 子プロセスが正常に作成されたことを意味し, 現在のプロセスは子プロセスです.
fork 関数の戻り値が 0 より大きい場合,戻り値が親プロセスの戻り値であることを意味します
(2) まとめ fork() wait() と組み合わせて使用する場合、親プロセスで wait() 関数をキャンセルしてみて、プロセスの実行状況を観察します。
wait() 関数の機能:親
プロセスが wait を呼び出すと、すぐに自身をブロックし、現在のプロセスが子プロセスを終了したかどうかを自動的に分析し、子プロセスがゾンビになっていることを検出した場合、 wait は、この子プロセスの情報を収集し、完全に破棄して戻ります; そのような子プロセスが見つからない場合、wait は、子プロセスが現れるまでここでブロックします。
Wait() 関数は、fork() 関数と組み合わせて使用する必要があります. fork() 関数の前に wait() 関数を使用すると、-1 を返します; 通常、親プロセスで呼び出され、PID を返します子プロセスの
親プロセスのwait()関数をキャンセルする.wait関数がないため,親プロセスはプロセスの最後まで実行され,その後子プロセスが実行されるとゾンビプロセスになる.実行結果は
(3) exec ファミリー関数の特定の使用法を要約して検証します。
6 つの関数と対応するパラメーターの使用方法
int execl(const char *path, const char *arg, …)
int execv(const char *path, char *const argv[])
int execle(const char *path, const char *arg , …, char *const envp[])
int execve(const char *path, char *const argv[], char *const envp[])
int execlp(const char *file, const char *arg, …)
int execvp( const char *file, char *const argv[])
関数の戻り値は成功です: 関数は戻りません
Error: return -1、失敗の理由は error に記録されます
execlp 関数を例にとると、execlp("/bin/ls", "ls -al", (char *)0); 現在のディレクトリ内のすべてのファイルを表示するには、"ls -al" を使用します。