C400

142. プロセス間通信のpipe (ChatGPTの初めての挑戦)

UNIXでプロセス間通信のpipeという関数が用意されている。
プロセスとはIBM iではジョブのことである。
一般的にpipeによるデータ交換のサンプル・ソースはインターネットでも
公開はされているがfork関数が使われている。
しかしIBM iではVer7.5でもどういうわけかfork関数は使うことができない。
そこでfork関数を使わないpipeによるプロセス間通信のサンプル・ソースを紹介する。・

[ TESTOYAP: 親プロセスのサンプル・ソース]

ソースはこちらから

0001.00 #include                                           
0002.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 #include                                         
0002.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でも解くことはできなかった。
それで社員に相談すると彼はあっさりとこの問題を解いてしまった。