UNIXでプロセス間通信のpipeという関数が用意されている。
プロセスとはIBM iではジョブのことである。
一般的にpipeによるデータ交換のサンプル・ソースはインターネットでも
公開はされているがfork関数が使われている。
しかしIBM iではVer7.5でもどういうわけかfork関数は使うことができない。
そこでfork関数を使わないpipeによるプロセス間通信のサンプル・ソースを紹介する。・
[ TESTOYAP: 親プロセスのサンプル・ソース]
ソースはこちらから
0001.00 #include0002.00 #include 0003.00 #include 0004.00 #include /* pipe */ 0005.00 #include 0006.00 #include 0007.00 0008.00 #define TRUE 0 0009.00 #define FALSE -1 0010.00 #define MSGSIZE 128 0011.00 0012.00 void main(void){ 0013.00 int pipe_fd[2] = {-1, -1}; 0014.00 int desc, len, spawn_fdmap[1], spw_fd_count; 0015.00 char sndbuf[MSGSIZE], rcvbuf[MSGSIZE], CmdStr[128]; 0016.00 char *spawn_argv[13], *spawn_envp[1]; 0017.00 struct inheritance inherit; 0018.00 pid_t pid; 0019.00 0020.00 printf("** TESTOYAP: 子供を呼出す pipe のテスト **n"); 0021.00 getchar(); 0022.00 0023.00 /*(1) 標準出力用 pipe を作成する */ 0024.00 pipe(pipe_fd); /* これで一対の pipe が完成 */ 0025.00 0026.00 /* 書き込み側の pipe の fd を教える */ 0027.00 spawn_argv[0] = (char*)&pipe_fd[1]; 0028.00 spawn_argv[1] = NULL; 0029.00 spawn_envp[0] = NULL; 0030.00 spw_fd_count = 1; 0031.00 spawn_fdmap[0] = pipe_fd[1]; 0032.00 strcpy(CmdStr, "/QSYS.LIB/TEST.COM.LIB/TESTKOP.PGM"); 0033.00 pid = spawn(CmdStr,spw_fd_count, spawn_fdmap, &inherit, spawn_argv, spawn_envp); 0034.00 /* 不要になったので close */ 0035.00 close(pipe_fd[1]); 0036.00 0037.00 read(pipe_fd[0], rcvbuf, sizeof(rcvbuf)-1); /* TESTKOP からのデータを読取る */ 0038.00 close(pipe_fd[0]); 0039.00 printf(" 親が受取ったのは TESTOYAP[%d] rcvbuf=[%s]n", __LINE__, rcvbuf); 0040.00 getchar(); 0041.00 }
[コンパイル]
CRTBNDC PGM(TEST.COM/TESTOYAP) SRCFILE(R540SRC/QCSRC2) DBGVIEW(*SOURCE) AUT(*ALL)
[ TESTKOP: 子プロセスのサンプル・ソース]
ソースはこちらから
0001.00 #include0002.00 #include 0003.00 #include 0004.00 #include /* pipe */ 0005.00 #include 0006.00 0007.00 #define TRUE 0 0008.00 #define FALSE -1 0009.00 #define MSGSIZE 128 0010.00 0011.00 void main(int argc, char* argv[]){ 0012.00 int pipe_fd, rc; 0013.00 char sndbuf[MSGSIZE], rcvbuf[MSGSIZE]; 0014.00 0015.00 pipe_fd = *(int*)&argv[1]; 0016.00 0017.00 strcpy(sndbuf, "** TESTKOP: これは標準出力です。 **"); 0018.00 rc = write(pipe_fd, sndbuf, sizeof(sndbuf)); 0019.00 close(pipe_fd); 0020.00 }
[コンパイル]
CRTBNDC PGM(TEST.COM/TESTKOP) SRCFILE(R540SRC/QCSRC2) DBGVIEW(*SOURCE) AUT(*ALL)
[実行]
call test.com/testoyap ** TESTOYAP: 子供を呼出す pipe のテスト ** > 親が受取ったのは TESTOYAP[46] rcvbuf=[** TESTKOP: これは標準出力です。 **]
[解説]
子プロセスが出力した「** TESTKOP: これは標準出力です。 **」という文字列が
親プロセスで受け取られて表示することができた。
非常に簡単なデータ通信として利用することができる。
※ ChatGPT の挑戦
実はこの2つのプログラムのpipeの同期はうまくいかなかった。
それでChatGPTに初めて相談したのがこのプログラムである。
ChatGPTはいろいろと教えてくれたのたので実力は大したものだと
驚いたのだが結局はChatGPTでも解くことはできなかった。
それで社員に相談すると彼はあっさりとこの問題を解いてしまった。