Linuxシステムプログラミング_9_プロセス制御のexec関数
exec関数
プロセスがexec関数を呼び出すと、そのプロセスの実行プログラムは完全に新しいプログラムに置き換えられます.新しいプログラムはmain関数から実行されます.
fork関数を使用してサブプロセスを作成すると、サブプロセスはexec関数を使用して別のプログラムを実行することが多い.
注意:exec関数を呼び出すと、新しいプロセスは作成されません.したがって、作成前後のプロセスIDは変更されません.execは、現在実行中のプログラムのコードセグメント、データセグメント、スタック、スタックを新しいプログラムで置き換えただけです.
#include
extern char **environ; 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 *filename, const char *arg, ...);
int execvp(const char *filename, char *const argv[]);
こんなにたくさんの関数はどのように記憶しますか?
アルファベットp付きで、最初のパラメータがfilenameであることを表し、PATH環境変数に基づいて実行可能なファイルを検索する.
アルファベットlを有する、代表関数はパラメータテーブルをとる.(アルファベットvと反発する;カンマで区切られたパラメータリストを受信し、リストはNULLポインタで終了フラグとする)
アルファベットvを有する、代表関数はargv[]をとる.(NULLで終わる文字列配列のポインタを受信したい)
アルファベットeを持つ、代表関数はenvp[]配列をとる.(関数は指定パラメータenvpを渡し、サブプロセスの環境を変更できます.接尾辞eがない場合、サブプロセスは現在のプログラムの環境を使用します)
次に例を示します.
実行結果:
. .. echo.sh main PID TTY TIME CMD 11120 pts/1 00:00:01 bash 20964 pts/1 00:00:00 main 20966 pts/1 00:00:00 ps F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 0 S 506 11120 11119 0 80 0 - 1745 - pts/1 00:00:01 bash 0 S 506 20964 11120 0 80 0 - 459 - pts/1 00:00:00 main 0 R 506 20967 20964 0 80 0 - 694 - pts/1 00:00:00 ps PID TTY TIME CMD 11120 pts/1 00:00:01 bash 20964 pts/1 00:00:00 main 20968 pts/1 00:00:00 ps F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 0 S 506 11120 11119 0 80 0 - 1745 - pts/1 00:00:01 bash 0 S 506 20964 11120 0 80 0 - 459 - pts/1 00:00:00 main 0 R 506 20969 20964 3 80 0 - 1618 - pts/1 00:00:00 ps
プロセスがexec関数を呼び出すと、そのプロセスの実行プログラムは完全に新しいプログラムに置き換えられます.新しいプログラムはmain関数から実行されます.
fork関数を使用してサブプロセスを作成すると、サブプロセスはexec関数を使用して別のプログラムを実行することが多い.
注意:exec関数を呼び出すと、新しいプロセスは作成されません.したがって、作成前後のプロセスIDは変更されません.execは、現在実行中のプログラムのコードセグメント、データセグメント、スタック、スタックを新しいプログラムで置き換えただけです.
#include
extern char **environ; 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 *filename, const char *arg, ...);
int execvp(const char *filename, char *const argv[]);
こんなにたくさんの関数はどのように記憶しますか?
アルファベットp付きで、最初のパラメータがfilenameであることを表し、PATH環境変数に基づいて実行可能なファイルを検索する.
アルファベットlを有する、代表関数はパラメータテーブルをとる.(アルファベットvと反発する;カンマで区切られたパラメータリストを受信し、リストはNULLポインタで終了フラグとする)
アルファベットvを有する、代表関数はargv[]をとる.(NULLで終わる文字列配列のポインタを受信したい)
アルファベットeを持つ、代表関数はenvp[]配列をとる.(関数は指定パラメータenvpを渡し、サブプロセスの環境を変更できます.接尾辞eがない場合、サブプロセスは現在のプログラムの環境を使用します)
次に例を示します.
#include
#include
#include
int main()
{
pid_t pid;
int status;
char *arg[] = {"ps" "-l", NULL};
// execl
pid = fork();
if(-1 == pid)
{
printf("Fork error!
");
return -1;
}
else if(0 == pid)
{
if(-1 == execl("/bin/ls", "ls", "-a", NULL))
{
perror("execl error!");
exit(-1);
}
}
waitpid(pid, &status, 0);
// execv
if(0 == (pid=fork()))
{
if(-1 == execv("/bin/ps", arg))
{
perror("execv error!");
exit(-1);
}
}
waitpid(pid, &status, 0);
// execle
if(0 == (pid=fork()))
{
if(-1 == execle("/bin/ps", "ps", "-l", NULL, NULL))
{
perror("execle error!");
exit(-1);
}
}
waitpid(pid, &status, 0);
// execve
if(0 == (pid=fork()))
{
if(-1 == execve("/bin/ps", arg, NULL))
{
perror("execve error!");
exit(-1);
}
}
waitpid(pid, &status, 0);
// execlp
if(0 == (pid=fork()))
{
if(-1 == execlp("ps", "ps", "-l", NULL))
{
perror("execle error!");
exit(-1);
}
}
waitpid(pid, &status, 0);
return 0;
}
実行結果:
. .. echo.sh main PID TTY TIME CMD 11120 pts/1 00:00:01 bash 20964 pts/1 00:00:00 main 20966 pts/1 00:00:00 ps F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 0 S 506 11120 11119 0 80 0 - 1745 - pts/1 00:00:01 bash 0 S 506 20964 11120 0 80 0 - 459 - pts/1 00:00:00 main 0 R 506 20967 20964 0 80 0 - 694 - pts/1 00:00:00 ps PID TTY TIME CMD 11120 pts/1 00:00:01 bash 20964 pts/1 00:00:00 main 20968 pts/1 00:00:00 ps F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 0 S 506 11120 11119 0 80 0 - 1745 - pts/1 00:00:01 bash 0 S 506 20964 11120 0 80 0 - 459 - pts/1 00:00:00 main 0 R 506 20969 20964 3 80 0 - 1618 - pts/1 00:00:00 ps