プロセスの生成
#include<stdio.h>
#include <unistd.h>
main(){
int i;
printf("\t(%s)プロセスID.....%d\n","元",getpid());
printf("\t(%s)親プロセスID...%d\n","元",getppid());
if((i=fork())==0)
{ //子プロセスで実行する部分
printf("\t子プロセスでのfork()の値 : %d\n",i);
printf("\t(%s)プロセスID.............%d\n","子",getpid());
printf("\t(%s)親プロセスID...........%d\n","子",getppid());
printf("子プロセスを終了します\n");
}
else{//親プロセスで実行する部分
printf("\t親プロセスでのfork()の値 : %d\n",i);
printf("\t(%s)プロセスID.............%d\n","親",getpid());
printf("\t(%s)親プロセスID...........%d\n","親",getppid());
printf("親プロセスを終了します\n");
}
}
fork関数の振る舞いについてです。
上記のプログラムをgccでコンパイルして実行した場合出力結果が
/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
(元)プロセスID.....375
(元)親プロセスID...246
親プロセスでのfork()の値 : 376
子プロセスでのfork()の値 : 0
(子)プロセスID.............376
(子)親プロセスID...........375
子プロセスを終了します
(親)プロセスID.............375
(親)親プロセスID...........246
親プロセスを終了します
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
という感じで出力されました。
fork関数がプロセスの複製を行っていることと、戻り値が0と376の2つであることはわかりました。
また子プロセスには0を親プロセスには376を返すこともわかりました。
感覚的にはif文の真である子プロセス側の記述文と偽である親プロセス側
の記述文が同時に実行されているのではないかと考えましたが
同時に実行されているのに
printf("\t子プロセスでのfork()の値 : %d\n",i);
printf("\t親プロセスでのfork()の値 : %d\n",i);
で表示される値が違うのはなぜでしょうか。
i=fork()によって代入されているのはわかるのですが、
同時に実行されつつ何故2つの違う値をiは出力できるのかがわかりません。
また出力結果が
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
(元)プロセスID.....377
(元)親プロセスID...246
親プロセスでのfork()の値 : 378
(親)プロセスID.............377
(親)親プロセスID...........246
親プロセスを終了します
子プロセスでのfork()の値 : 0
(子)プロセスID.............378
(子)親プロセスID...........1
子プロセスを終了します
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
子プロセスから見たときの親プロセスが1となっているのは何故でしょうか?
本来ならば377ではないでしょうか?
わかりにくい説明ですいません。
よろしくお願いします。
補足
具体的には以下のようなソースを作成中であり、 以下であれば1件目の受信メールを任意ファイルに 保存されます。 しかし、メール有無の判定方法がわからないため No Mail For User と言うメッセージが出力されてしまいます。 コマンド実行の結果を標準出力させたくないのですが、 以下の方法だと出力されてしまい・・・。 メール有無は出力後のファイルサイズなどを調査するしかないでしょうか? /* パイプの作成 */ Rc = pipe(PipeFd) ; if (Rc) { return -1; } Rc = pipe(PipeStdOut) ; if (Rc) { return -1; } /* 子プロセスの生成 */ Pid = fork() ; if (Pid == -1) { close(PipeFd[1]) ; close(PipeFd[0]) ; return -1; } /* 子プロセスの処理 */ if (Pid == 0) { if (close(PipeFd[1])) { exit(1) ; } if (close(PipeStdOut[0])) { exit(1) ; } /* パイプを標準入力へ */ if (close(STDIN_FILENO)) { exit(1) ; } if (dup(PipeFd[0]) == -1) { exit(1) ; } if (close(PipeFd[0])) { exit(1) ; } /* メッセージを表示しない*/ if (close(STDOUT_FILENO)) { exit(1) ; } if (dup(PipeStdOut[1]) == -1) { exit(1) ; } if (close(PipeStdOut[1])) { exit(1) ; } /* メーラを実行 */ execlp("mailx","mailx",NULL) ; exit(1) ; } /* 親プロセスの処理 */ if (close(PipeFd[0])) { kill(Pid,SIGKILL) ; wait((int *)NULL) ; close(PipeFd[1]) ; return -1; } if (close(PipeStdOut[1])) { kill(Pid,SIGKILL) ; wait((int *)NULL) ; close(PipeFd[1]) ; return -1; } /* 標準入力へ指示する */ sprintf(Buf,"s %s\nq\n","/home/user/mbox") ; Length = strlen(Buf) ; if (write(PipeFd[1],(void *)Buf,Length) != Length) { if (errno != EPIPE) { kill(Pid,SIGKILL) ; wait((int *)NULL) ; close(PipeFd[1]) ; return -1; } } if (close(PipeFd[1])) { kill(Pid,SIGKILL) ; wait((int *)NULL) ; return -1; } /* 子プロの標準出力を捨てる*/ while( read(PipeStdOut[0], (void *)Buf,sizeof(Buf)) ) ; if (close(PipeStdOut[0])) { kill(Pid,SIGKILL) ; wait((int *)NULL) ; return -1; } Rc = (int)wait((int *)NULL) ; if (Rc == -1) { return -1; } return 0;