パイプラインシステムコールに関連する構造を理解しようとしています。
int pipe(int pipefd[2]);
pipefd[0]
私が理解したのは、パイプの読み取りと書き込みの終わりに関連する「読み取り」および「書き込み」カーネルバッファ/構造があることです。pipefd[1]
私は本当にこのパイプの読み取り/書き込みの終わりにある構造へのいくつかのポインタ(恥ずかしい意図はありません)が欲しいです。私はこれが単にファイル記述子だと思います。たとえば、コンピュータは、次のように、読み込み操作中に転送する「読み取る」バイトがなくなったことをどのように知ることができますか?
char tmpBuff[15];
bytesRead = read(filedes[0], tmpBuff, 15);
filedes[0]
あるいは、記述子にfiledes[1]
関連するバッファ、ファイルの場所などを追跡するためにどの構造が定義されていますか?
マニュアルページによるとssize_t read(int fd, void *buf, size_t count);
(2) Linux プログラママニュアルを読む
NAME 読み取り - ファイル記述子から読み込みます。
まとめ#include
ssize_t read(int fd, void *buf, size_t count);
戻り値成功したときに読み取られたバイト数を返します(0はファイルの終わりを示します)。ファイルの場所はその番号だけ進められます。
以下の構造を形成するには、ファイル記述子参照のインデックスを指す構造が必要です。
struct file_info
{
char *start_buf;
char *end_buf;
int fileposition;
};
最後に、好奇心では、ユーザー空間でこれらの値にアクセスして、「ファイル記述子fooから読み取ろうとしていますが、現在のバッファに120バイトがあり、ファイルの場所0です」というプログラムを作成することは可能ですか?バッファはユーザーレベルでアクセスできないので(私の意見では)ファイル記述子の値だけを知っていて、この情報にどのようにアクセスできますか?
ベストアンサー1
まず、あなたの質問に対する答えは次のとおりです。 パイプバッファはどれくらい大きいですか?
パイプはカーネルが維持する限られた循環バッファです。このpipe
システムコールは新しいパイプを作成し、2つのファイル記述子をパイプに関連付けます。 1つはパイプに書き込むためのもの、もう1つはパイプから読み取るためのものです。
関連ファイル記述子を介してパイプに書き込み、スペースがある場合は、指定されたデータをこのバッファにコピーします。データ用のスペースがない場合、write()呼び出しはスペースが利用可能になるまで呼び出しアプリケーションをブロックします。パイプがwrite()操作中にプロセスをブロックし、他のプロセス/スレッドがパイプから十分なデータを読み取り、ブロックされたライターが書き込みを完了できるようになると、ブロックされた書き込みは目を覚ますと許可されます。続く。
読者にもその過程は似ている。読み取りプロセスがパイプからデータを読み取ろうとしましたが、読み取る内容がない場合、read()システムコールはデータが利用可能になるのを待ちません。 Popeの読み取り()操作中にプロセスがブロックされ、他のプロセス/スレッドがパイプにデータを書き込んでブロックされたリーダーが読み取りを完了できるようになると、ブロックされた読み取りはプロセッサから起動され、許可されます。続く。
パイプサイズに関しては、次のマニュアルページのエントリでいくつかの情報を見つけることができますman 7 pipe
。
パイプ容量
A pipe has a limited capacity. If the pipe is full, then a write(2) will block or fail, depending on whether the O_NONBLOCK flag is set (see below). Different implementations have different limits for the pipe capacity. Applications should not rely on a particular capacity: an application should be designed so that a reading process consumes data as soon as it is available, so that a writing process does not remain blocked. In Linux versions before 2.6.11, the capacity of a pipe was the same as the system page size (e.g., 4096 bytes on i386). Since Linux 2.6.11, the pipe capacity is 65536 bytes. Since Linux 2.6.35, the default pipe capacity is 65536 bytes, but the capacity can be queried and set using the fcntl(2) F_GETPIPE_SZ and F_SETPIPE_SZ operations. See fcntl(2) for more information.
以下は、パイプの寸法を照会するサンプルプログラムです。
#define _GNU_SOURCE
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int pipefds[2] = { -1, -1 };
assert(pipe(pipefds) == 0);
printf("pipe size: %d\n", fcntl(pipefds[0], F_GETPIPE_SZ));
// pipe will be closed on exit
return EXIT_SUCCESS;
}
プログラムを実行すると、次のようになります。
$ ./a.out
pipe size: 65536