popen / pclose を利用したプロセスの起動では、"cat makefile | wc" のようなシェル上で利用するパイプによるコマンドを渡すことも可能です。
リダイレクションによる実装例は こちら
実行結果
popen / pclose を利用したプロセスの起動では、"cat makefile | wc" のようなシェル上で利用するパイプによるコマンドを渡すことも可能です。
リダイレクションによる実装例は こちら
実行結果
リダイレクションにより子プロセスから出力される文字列を親プロセスへと渡しています。
ping コマンド等、C言語などにて実装が困難な処理を外部コマンドとして呼び出し、その結果にて処理を分岐する用途に使う際に便利になります。
実行結果
以下の例では、クライアントから送られたメッセージをそのまま送り返す echo 機能を持ったサーバと、そのサーバと通信を行うためのクライアントの実装を行っています。
ソース等をまとめたもの:DL(tcpsvcl.zip)
サーバー
クライアント
TCP ライブラリ: tcp_lib.cpp TCP ライブラリ: tcp_lib.h
実行結果(サーバー側) 実行結果(クライアント側)
main 関数内での mypopen, mypclose 関数の利用例はそのまま popen, pclose でも利用可能です。
実行結果
execlp(execvp,..) 関数は引数に実行するコマンドとその引数を指定すると、そのコマンドを実行してくれますが、実行後プログラムを終了してしまいます。
そこで、そのコマンドを実行後も処理を続行したい場合には、fork により子プロセスを作成し、その子プロセス内にて execlp 等を実行しています。
execlp 関数の終了後、子プロセスが終了しても親プロセスで続けて処理を行うことができます。
また、execlp 関数では、通常のシェルで行うようなパイプやリダイレクション処理 ( | < > etc.) や正規表現 (? * etc.) による複雑な処理を行うことができません。
複雑な処理を行う場合にはシェルコマンド (/bin/sh etc.) を介してコマンドを実行します。
ex.
execlp("/bin/sh","/bin/sh","-c","ls | wc > output.txt",NULL);
実行結果
例題では、2つのプロセスを起動し、それぞれのプロセスからの入出力をリダイレクトしています。
実行結果
例題では、標準入力を引数1で指定されたファイル、標準出力を引数2で指定されたファイルへ変更し、入力で与えられる文字列の行数を wc コマンドを実行することによりカウントし、出力しています。
結果は引数2のファイルへと保存されます。
実行結果
双方向の通信を行う例として、pipe() 関数により2本のパイプを準備する方法と、socketpair() 関数により双方向通信が可能なファイル記述子を準備する方法の2通りが考えられます。
以下では、それぞれの方法についての例を示します。
2本のパイプを準備する方法 実行結果
双方向通信が可能なファイル記述子を準備する方法 実行結果
dup (or dup2) によるリダイレクション用い、標準入出力をパイプで接続し通信を行っています。
リダイレクションを用いることにより、プロセス間の通信に高水準入出力関数を用いることが可能となります。
子側はプロセスの終了とともにファイルディスクリプタが閉じられ、親側の受信の受信が完了します。
親から子へ 実行結果
子から親へ 実行結果
親から子へメッセージを送信する場合には、親側の送信の最後にファイルディスクリプタを閉じなければ(close(pipe_fd[1]); の部分)、子側の受信が完了せず、プロセスが終了しない点に注意して下さい。
子側はプロセスの終了とともにファイルディスクリプタが閉じられ、親側の受信の受信が完了します。
双方向通信や高水準入出力関数を用いた例は こちら
親から子へ 実行結果 子から親へ
実行結果
今回は、子プロセス内にて数値を1秒後とにインクリメントして表示し、子プロセス自身が自らで終了しています。
外部からの入力等が無い限り終了しない、等の処理を行うことも可能です。
子プロセスは、システムに別のプロセスとしてきちんと認識されますので、タスクマネージャーや ps コマンドにより PID を指定して強制終了することも可能です。
例題では親プロセスの PID を表示していますので、親プロセスと同じ名前で PID が異なるものが子プロセスとなります。 実行結果
shmget() 共有メモリの識別子を得る
shmat() 自プロセスのメモリとして割り当てる
shmdt() 自プロセスのメモリから外す
shmctl() 共有メモリの制御を行う(共有メモリの削除も可能)