파이프라인 시스템 호출과 관련된 구조를 이해하려고 합니다.
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
시스템 호출은 새 파이프를 생성하고 두 개의 파일 설명자를 파이프와 연결합니다. 하나는 파이프에 쓰기 위한 것이고 다른 하나는 파이프에서 읽기 위한 것입니다.
연관된 파일 설명자를 통해 파이프에 쓰고, 공간이 있으면 지정된 데이터를 이 버퍼에 복사합니다. 데이터를 위한 공간이 없는 경우 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