|
≫ |
|
|
|
HP OpenVMS HP C ランタイム・ライブラリ・リファレンス・マニュアル (上巻)
-
vfork関数は,
exec呼び出しの戻りアドレスを設定するために呼び出されます。
vfork関数は通常,
if文の式で使用されます。この構造では,1 つの戻り値が 0 で,もう 1 つが 0 以外であるため,
vforkの 2 つの戻りアドレスを利用できます。
-
vforkを最初に呼び出すと,戻り値 0 が返され,親は
vfork呼び出しに関連付けられた
else句を実行し,その結果,
execlが呼び出されます。
-
exec関数が異常終了すると,負の子プロセス ID が返されます。これらの条件に関して戻り値が確認されます。
-
wait関数は,親プロセスと子プロセスの同期をとるために使用されます。
-
exec関数は,子プロセスで起動されるイメージが存在しない場合でも,この時点まで正常終了を示す可能性があるため,親が子プロセスの戻り状態を調べて,定義済み状態 CLI$_IMAGEFNF (ファイルが見つからない) が返されていないかどうか確認します。
例 5-2 では,親は子プロセスに引数を渡します。
/* CHAP_5_CHILDARG.C */
/* In this example, the arguments are placed in an array, gargv, */
/* but they can be passed to the child explicitly as a zero- */
/* terminated series of character strings. The child program in this */
/* example writes the arguments that have been passed it to stdout. */
#include <climsgdef.h>
#include <stdio.h>
#include <stdlib.h>
#include <perror.h>
#include <processes.h>
const char *child_name = "chap_5_childarg_child.exe" ;
main()
{
int status,
cstatus;
char *gargv[] =
{"Child", "ARGC1", "ARGC2", "Parent", 0};
if ((status = vfork()) != 0) {
if (status < -1)
printf("Parent - Child process failed\n");
else {
printf("Parent - waiting for Child\n");
if ((status = wait(&cstatus)) == -1)
perror("Parent - Wait failed");
else if (cstatus == CLI$_IMAGEFNF)
printf("Parent - Child does not exist\n");
else
printf("Parent - Child final status: %x\n",
cstatus);
}
}
else {
printf("Parent - Starting Child\n");
if ((status = execv(child_name, gargv)) == -1) {
perror("Parent - Exec failed");
exit(EXIT_FAILURE);
}
}
}
--------------------------------------------------------
/* CHAP_5_CHILDARG_CHILD.C */
/* This is a child program that echos its arguments */
#include <stdio.h>
main(argc, argv)
int argc;
char *argv[];
{
int i;
printf("Program name: %s\n", argv[0]);
for (i = 1; i < argc; i++)
printf("Argument %d: %s\n", i, argv[i]);
return(255) ;
}
|
例 5-3 は,
wait関数を使用して,同時に実行される複数の子の最終状態を確認する方法を示しています。
/* CHAP_5_CHECK_STAT.C */
/* In this example 5 child processes are started. The wait() */
/* function is placed in a separate for loop so that it is */
/* called once for each child. If wait() were called within */
/* the first for loop, the parent would wait for one child to */
/* terminate before executing the next child. If there were */
/* only one wait request, any child still running when the */
/* parent exits would terminate prematurely. */
#include <climsgdef.h>
#include <stdio.h>
#include <stdlib.h>
#include <perror.h>
#include <processes.h>
const char *child_name = "chap_5_check_stat_child.exe" ;
main()
{
int status,
cstatus,
i;
for (i = 0; i < 5; i++) {
if ((status = vfork()) == 0) {
printf("Parent - Starting Child %d\n", i);
if ((status = execl(child_name, 0)) == -1) {
perror("Parent - Exec failed");
exit(EXIT_FAILURE);
}
}
else if (status < -1)
printf("Parent - Child process failed\n");
}
printf("Parent - Waiting for children\n");
for (i = 0; i < 5; i++) {
if ((status = wait(&cstatus)) == -1)
perror("Parent - Wait failed");
else if (cstatus == CLI$_IMAGEFNF)
printf("Parent - Child does not exist\n");
else
printf("Parent - Child %X final status: %d\n",
status, cstatus);
}
}
|
例 5-4 は,
pipe関数と
dup2関数を使用して,特定のファイル記述子を通じて親プロセスと子プロセスの間で通信する方法を示しています。
#defineプリプロセッサ・ディレクティブは,プリプロセッサ定数
inpipeと
outpipeをファイル記述子 11 と 12 の名前として定義します。
/* CHAP_5_PIPE.C */
/* In this example, the parent writes a string to the pipe for */
/* the child to read. The child then writes the string back */
/* to the pipe for the parent to read. The wait function is */
/* called before the parent reads the string that the child has */
/* passed back through the pipe. Otherwise, the reads and */
/* writes will not be synchronized. */
#include <perror.h>
#include <climsgdef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <processes.h>
#include <unixio.h>
#define inpipe 11
#define outpipe 12
const char *child_name = "chap_5_pipe_child.exe" ;
main()
{
int pipes[2];
int mode,
status,
cstatus,
len;
char *outbuf,
*inbuf;
if ((outbuf = malloc(512)) == 0) {
printf("Parent - Outbuf allocation failed\n");
exit(EXIT_FAILURE);
}
if ((inbuf = malloc(512)) == 0) {
printf("Parent - Inbuf allocation failed\n");
exit(EXIT_FAILURE);
}
if (pipe(pipes) == -1) {
printf("Parent - Pipe allocation failed\n");
exit(EXIT_FAILURE);
}
dup2(pipes[0], inpipe);
dup2(pipes[1], outpipe);
strcpy(outbuf, "This is a test of two-way pipes.\n");
status = vfork();
switch (status) {
case 0:
printf("Parent - Starting child\n");
if ((status = execl(child_name, 0)) == -1) {
printf("Parent - Exec failed");
exit(EXIT_FAILURE);
}
break;
case -1:
printf("Parent - Child process failed\n");
break;
default:
printf("Parent - Writing to child\n");
if (write(outpipe, outbuf, strlen(outbuf) + 1) == -1) {
perror("Parent - Write failed");
exit(EXIT_FAILURE);
}
else {
if ((status = wait(&cstatus)) == -1)
perror("Parent - Wait failed");
if (cstatus == CLI$_IMAGEFNF)
printf("Parent - Child does not exist\n");
else {
printf("Parent - Reading from child\n");
if ((len = read(inpipe, inbuf, 512)) <= 0) {
perror("Parent - Read failed");
exit(EXIT_FAILURE);
}
else {
printf("Parent: %s\n", inbuf);
printf("Parent - Child final status: %d\n",
cstatus);
}
}
}
break;
}
}
------------------------------------------------------------------
/* CHAP_5_PIPE_CHILD.C */
/* This is a child program which reads from a pipe and writes */
/* the received message back to its parent. */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define inpipe 11
#define outpipe 12
main()
{
char *buffer;
int len;
if ((buffer = malloc(512)) == 0) {
perror("Child - Buffer allocation failed\n");
exit(EXIT_FAILURE);
}
printf("Child - Reading from parent\n");
if ((len = read(inpipe, buffer, 512)) <= 0) {
perror("Child - Read failed");
exit(EXIT_FAILURE);
}
else {
printf("Child: %s\n", buffer);
printf("Child - Writing to parent\n");
if (write(outpipe, buffer, strlen(buffer) + 1) == -1) {
perror("Child - Write failed");
exit(EXIT_FAILURE);
}
}
exit(EXIT_SUCCESS);
}
|
|