UNIX の C言語:forkとexec
技術ドキュメント目次 -> UNIX の C言語 -> forkとexec本技術ドキュメントは、2002~2004年頃に作成したものが多いです。
内容が古くなっていることもあるかと思いますが、ご了承ください。
【低価格SSL証明書】弊社運営の低価格SSL証明書販売サイト、翌月末払いなど請求書払いも可能。
◆ forkとexec
fork() と exec()系関数はを理解することは重要です。それぞれ次のような動作をします。
fork: プロセスのコピーを作成。 exec系: プロセスを引数で指定したプロセスに置き換える |
◆ たとえば、パフォーマンステストプログラムで、(少々無理矢理な例です)
例えば、負荷テスト・パフォーマンス測定などの目的で、特定のプログラムを多重に実行させたい時に、
下記のようにコマンドを連打することがるかもしれません。
ただし、そのようにしていると、
オペレーションがすこしめんどくさいですし、
オペミスも発生する可能性が高くなってしまいます。
$ /(PATH)/somecmd arg1 arg2 arg3 & $ /(PATH)/somecmd arg1 arg2 arg3 & $ /(PATH)/somecmd arg1 arg2 arg3 & $ /(PATH)/somecmd arg1 arg2 arg3 & .... |
文末の fork.c のようなプログラムを作成し、
コンパイル(gcc -o fork fork.c)し、
下記のように引数を指定して実行することで、
/(PATH)/somecmd arg1 arg2 arg3 コマンドを多重度10で実行できることができます。
オペレーションが楽&正確になるので、
C言語でテストプログラムを作成したときなどに、便利かもしれません。
./fork 10 /(PATH)/somecmd arg1 arg2 arg3 |
◆ サンプルプログラム解説
fork() は実行中のプロセスが自分自身の分身を作成を作成します。新たに作成されたプロセス(子)であるか、
もともと存在していたプロセス(親)であるかは、
fork の戻り値で判断することができます。
また、
exec系関数を呼び出すことで、
実行中のプロセスが、引数で指定した別のプロセスに置き換わります。
(exec系関数には複数の種類があるので、manページもよくご参照ください。)
下記のサンプルでは、
fork() して作成した子プロセスが、
exec()系関数を呼び出し、目的のプログラムを実行しています。
※RedHat Linux 7.3 と FreeBSD 5.3 でコンパイルが通ることを確認しました。
/* * fork.c * * Copyright (C) 2006 Slogical Corporation */ #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <dirent.h> int main (int argc, char **argv) { int i; int repeat; DIR *dir; /* 引数のチェック */ if (argc < 3 || strncmp(argv[1], "-h", 2) == 0) { fprintf(stderr, "1st arg is repeat count.\n"); fprintf(stderr, "2nd arg is target command(start with '/').\n"); fprintf(stderr, "over 3rd args are args for target command.\n"); return 1; } repeat = atoi(argv[1]); if (repeat < 1) { fprintf(stderr, "1st arg is repeat count.\n"); fprintf(stderr, "please input numeric(over 1) value.\n"); return -1; } if (strncmp(argv[2], "/", 1) != 0) { fprintf(stderr, "2nd arg is target command(start with '/').\n"); fprintf(stderr, "please input a value started with '/'.\n"); return -1; } if (access(argv[2], X_OK) != 0) { fprintf(stderr, "can not exec %s\n", argv[2]); return -1; } dir = opendir(argv[2]); if (dir != NULL) { fprintf(stderr, "%s is directory can not execute.\n", argv[2]); closedir(dir); return -1; } /* 指定された回数だけ繰り返す */ for (i=0; i<repeat; i++) { /* fork した子プロセスが処理を実行 */ pid_t pid = fork(); if (pid == 0) { execvp(argv[2], &argv[2]); } } return 0; } |
■ UNIX の C言語 についての他のドキュメント
■ 他のグループのドキュメント
Apache / Linux / FreeBSD / OpenSSL / Perl / HTTPプロトコル / Jakarta Tomcat / Java / NetBSD / Oracle / PostgreSQL / UNIX の C言語 / UNIX のコマンド / Windows / bind / システム運用TIPS