システム・プログラム 電子・情報工学系 新城 靖 <yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
http://www.hlla.is.tsukuba.ac.jp/~yas/coins/syspro-2000/2000-05-01
/process-fork.html
あるいは、次のページから手繰っていくこともできます。
http://www.hlla.is.tsukuba.ac.jp/~yas/coins/
http://www.is.tsukuba.ac.jp/~yas/index-j.html
UNIX では、新たにプロセスを作る時に、自分のコピーしか作れない(fork()シ ステム・コール)。元のプロセスを親プロセス、作られたプロセスを子プロセ スという。
現在のプログラムの実行はそのまま続けて、新しくプログラムを実行するには、 次のようにする。
---------------------------------------------------------------------- 1: /* 2: proc-create.c -- calプログラムよりプロセスを作る 3: ~yas/syspro1/proc/proc-create.c 4: $Header: /home/lab2/OS/yas/syspro1-1998/proc/RCS/proc-create.c,v 1.3 1998/05/25 14:58:24 yas Exp $ 5: Start: 1995/02/27 15:27:54 6: */ 7: 8: #include <unistd.h> /* pid_t */ 9: 10: extern char **environ; 11: 12: main() 13: { 14: pid_t child_pid ; 15: if( (child_pid=fork()) == 0 ) 16: { 17: char *argv[4] ; 18: printf("child: pid == %d, ppid == %d\n", getpid(), getppid() ); 19: argv[0] = "cal" ; 20: argv[1] = "5" ; 21: argv[2] = "1998" ; 22: argv[3] = 0 ; 23: execve( "/usr/bin/cal", argv, environ ); 24: perror( "execve" ); 25: /* exec に失敗したら exit() を忘れないこと */ 26: exit( 1 ); 27: } 28: else if( child_pid > 0 ) 29: { 30: printf("parent: pid == %d, ppid == %d, child_pid == %d\n", 31: getpid(), getppid(),child_pid ); 32: } 33: else 34: { 35: perror("fork"); 36: } 37: } ----------------------------------------------------------------------実行例。
execve() は、システム・コールである。これを使いやすくするために、次の ようなライブラリ関数が用意されている。---------------------------------------------------------------------- % ./proc-createchild: pid == 27405, ppid == 27404 parent: pid == 27404, ppid == 27288, child_pid == 27405 % 1998 年 5 月 日 月 火 水 木 金 土 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
%
% ./proc-create
child: pid == 27429, ppid == 27428 1998 年 5 月 日 月 火 水 木 金 土 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 parent: pid == 27428, ppid == 27288, child_pid == 27429 %
----------------------------------------------------------------------
int execl (const char *path, const char *arg0, ..., const char *argn, (char *)0); int execv (const char *path, char *const *argv); int execle (const char *path, const char *arg0, ..., const char *argn, (char *0), const char *envp[]); int execve (const char *path, char *const *argv, char *const *envp); int execlp (const char *file, const char *arg0, ..., const char *argn, (char *)0); int execvp (const char *file, char *const *argv); int system(const char *string); FILE *popen(const char *command, const char *type); int pclose (FILE *stream);
proc-create
を実行すると、上のように、親プロセスの出力と子
プロセスの出力が入り交じることがある。この理由を考えなさい。
この問題を解決しなさい。そのためには、wait() システム・コール (waitpid(),wait3(),wait4()など)を用いて、同期を行えばよい。すなわち、 子プロセスが表示する可能性がある間は、親プロセスを待ち状態にしなさい。