Linuxプロセス間通信:パイプ(パイプを標準入力と標準出力として使用)
#include<unistd.h>
int dup(int file_descriptor);
int dup2(int file_descriptor_one , int file_descriptor_two);
dup呼び出しの目的はopen呼び出しと少し似た新しいファイル記述子を開くことです.異なる点は、dup呼び出しによって作成された新しいファイル記述子が、そのパラメータである既存のファイル記述子と同じファイル(またはパイプ)を指すことである.dup 2作成された新しいファイル記述子またはパラメータfile_descriptor_twoは同じか、パラメータより大きい最初の使用可能な値です.
closeとdup関数でファイル記述子を処理する
ファイル記述子初期値ファイル記述子0を閉じた後dup呼び出し後
0標準入力{クローズ済}パイプファイル記述子
1標準出力標準出力標準出力
2標準エラー出力標準エラー出力標準エラー出力
3パイプファイル記述子パイプファイル記述子パイプファイル記述子
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
int data_processed;
int file_pipes[2];
const char some_data[] = "123";
pid_t fork_result;
if (pipe(file_pipes) == 0) {
fork_result = fork();
if (fork_result == (pid_t)-1) {
fprintf(stderr, "Fork failure");
exit(EXIT_FAILURE);
}
if (fork_result == (pid_t)0) {
close(0);
dup(file_pipes[0]);
close(file_pipes[0]);
close(file_pipes[1]);
execlp("od", "od", "-c", (char *)0);
exit(EXIT_FAILURE);
}
else {
close(file_pipes[0]);
data_processed = write(file_pipes[1], some_data,
strlen(some_data));
close(file_pipes[1]);
printf("%d - wrote %d bytes
", (int)getpid(), data_processed);
}
}
exit(EXIT_SUCCESS);
}
コマンド配管:FIFO
コマンドラインに名前付きパイプを作成したり、プログラムで作成したりできます.従来、コマンドラインでunキーネーミングパイプを差するために使用されたプログラムはmknodであり、以下に示す.
mknod filename p
ただし、mknodコマンドはX/OPEN仕様のコマンドリストには表示されません.だからすべてのクラスunixシステムがそうできるわけではないかもしれません.推奨されるコマンドラインは、次のとおりです.
mkfifo filename
プログラムでは、次のように2つの関数呼び出しを使用してパイプを作成できます.
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo( const char *filename , mode_t mode);
int mknod(const char *filename , mode_t mode | S_IFIFO , (dev_t ) 0 );
名前付きパイプの作成#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
int main()
{
int res = mkfifo("/tmp/my_fifo", 0777);
if (res == 0)
printf("FIFO created
");
exit(EXIT_SUCCESS);
}
FIFOファイルへのアクセス(1)まず、この(空の)FIFOファイルを読んでみましょう
$ cat (2)今、FIFOにデータを書き込んでみます.最初のコマンドはFIFOにデータが表示されるまで保留されているため、別の割り込みで次のコマンドを実行する必要があります.
$ echo "hello world" >/tmp/my_fifo
(3)最初のコマンドをバックグラウンドで実行することで,2つのコマンドを一度に実行することができる.
$ cat $ echo "hello world">/tmp/my_fifo
Open()を使用してFIFOファイルを開くと、O_NONBLOCKフラグが影響する1、O_を使用する場合NONBLOCKフラグの場合、FIFOファイルを開いて読み込む操作はすぐに返されますが、FIFOファイルを開いて読み込むプロセスが他にない場合は、書き込まれた操作はENXIOエラーコードを返します.2、O_を使用していないNONBLOCKフラグの場合、FIFOを開いて読み込む操作は、他のプロセスがFIFOファイルを開いて書き込むまで待機します.同様に、FIFOファイルを開いて書き込む操作は、他のプロセスがFIFOファイルを開いて読み取りに来るまで正常に戻ります.戻り値が成功すると0を返し、そうでない場合は-1を返し、エラーの原因はerrnoに保存されます.エラーコードEACCESSパラメータpathnameで指定されたディレクトリパスに実行可能な権限EEXISTパラメータpathnameで指定されたファイルは既に存在しません.ENAMETOOLONGパラメータpathnameのパス名が長すぎます.ENOENTパラメータpathnameに含まれるディレクトリは存在しないENOSPCファイルシステムの空き領域はENOTDERパラメータpathnameパスのディレクトリには存在しないが、本物のディレクトリではない.EROFSパラメータpathnameで指定されたファイルは、読み取り専用ファイルシステム内に存在します.
// Let's start with the header files, a #define and the check that the correct number
// of command-line arguments have been supplied.
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#define FIFO_NAME "/tmp/my_fifo"
int main(int argc, char *argv[])
{
int res;
int open_mode = 0;
int i;
if (argc < 2) {
fprintf(stderr, "Usage: %s <some combination of\
O_RDONLY O_WRONLY O_NONBLOCK>
", *argv);
exit(EXIT_FAILURE);
}
// Assuming that the program passed the test, we now set the value of open_mode
// from those arguments.
for(i = 1; i < argc; i++) {
if (strncmp(*++argv, "O_RDONLY", 8) == 0)
open_mode |= O_RDONLY;
if (strncmp(*argv, "O_WRONLY", 8) == 0)
open_mode |= O_WRONLY;
if (strncmp(*argv, "O_NONBLOCK", 10) == 0)
open_mode |= O_NONBLOCK;
}
// We now check whether the FIFO exists and create it if necessary.
// Then the FIFO is opened and output given to that effect while the program
// catches forty winks. Last of all, the FIFO is closed.
if (access(FIFO_NAME, F_OK) == -1) {
res = mkfifo(FIFO_NAME, 0777);
if (res != 0) {
fprintf(stderr, "Could not create fifo %s
", FIFO_NAME);
exit(EXIT_FAILURE);
}
}
printf("Process %d opening FIFO
", getpid());
res = open(FIFO_NAME, open_mode);
printf("Process %d result %d
", getpid(), res);
sleep(5);
if (res != -1) (void)close(res);
printf("Process %d finished
", getpid());
exit(EXIT_SUCCESS);
}