プロセス置換の基本概念
プロセス生成後、親プロセスと子プロセスは同じコード領域を共有します。この状態では、子プロセスは親プロセスのコードのみを実行可能です。
しかし、実際のニーズでは、子プロセスが親プロセスとは異なるコードを実行できるようにする必要があります。これにより、両プロセスが異なるタスクを実行できるようになり、処理効率が向上します。
プロセス置換とは、既存のプロセスのコード領域を新しいプログラムで置き換えることを指します。これにより、プロセスは新しいプログラムを実行できます。
プロセス置換の実装
一般的には、親プロセスがfork()で子プロセスを作成し、子プロセス内でexec系関数を使用して新しいプログラムを実行します。
Linuxでは、execl, execv, execle, execveなどの関数が提供されています。
基本的な使用例
#include <stdio.h>
#include <unistd.h>
int main() {
printf("Before: PID=%d, PPID=%d\n", getpid(), getppid());
execl("/usr/bin/ls", "ls", "-l", NULL);
printf("After: PID=%d, PPID=%d\n", getpid(), getppid());
return 0;
}
上記コードでは、ls -lコマンドを実行します。execl以降のコードは実行されません。
マルチプロセスでの置換
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork();
if (pid == 0) {
printf("Before: PID=%d, PPID=%d\n", getpid(), getppid());
sleep(2);
execl("/usr/bin/ls", "ls", "-l", NULL);
_exit(1);
}
waitpid(pid, NULL, 0);
printf("Parent: Child process %d completed\n", pid);
return 0;
}
子プロセスでのみexeclが実行され、親プロセスには影響しません。
exec関数群の種類と特徴
execl: 引数をリスト形式で指定execv: 引数を配列で指定execle: 環境変数を指定可能execvp: PATH環境変数を使って実行ファイルを検索
環境変数の扱い
環境変数は親プロセスから子プロセスに継承されます。ただし、execleなどを使って明示的に環境変数を指定した場合、既存の環境変数は上書きされます。
プロセス置換の注意点
- 置換成功後、元のプロセスのコードは破棄され、以降のコードは実行されません。
- 置換失敗時は関数から戻り値が返ります。
- 新しいプロセスは作成されず、PIDは変更されません。
execveシステムコール
exec関数群はすべてexecveというシステムコールを内部で使用します。
int execve(const char *filename, char *const argv[], char *const envp[]);
この関数はカーネルレベルで実装されており、他のexec関数はすべてこのラッパー関数です。