다음의 콘텐츠를 크롤링한다고 가정해 보겠습니다.매우 큰파일이지만 한 번에 여러 부분을 보고 싶습니다. 다음을 수행한다고 가정해 보겠습니다.
$ cat /dev/sda1 | less
Java나 ActionScript와 같은 언어를 사용하는 프로그래머로서 이 코드를 보면 Bash가 먼저 명령을 실행하는 모습을 상상합니다 cat /dev/sda1
.모든 것명령을 RAM으로 다시 저장한 다음 less
으로 표시되는 매우 큰 "더미 변수"에 액세스할 수 있는 명령을 실행합니다 -
.
이것이 Bash가 작업을 수행하는 방식입니까(즉, 명령은특히 나쁘다파일이 시스템의 RAM 용량보다 큰 경우 다른 명령을 사용해야 한다고 생각하시나요? 아니면 대용량 데이터에 맞게 파이프라인을 최적화할 수 있는 방법이 있나요?
답변1
아니요, 모든 것을 메모리에 로드하는 것은 아니며 설계하기에 비현실적인 방법입니다. 버퍼를 사용하여 파이프 왼쪽의 출력을 버퍼링한 다음 이러한 버퍼를 파이프 오른쪽의 명령 입력에 연결합니다.
매뉴얼 페이지에는 man 7 pipe
다음과 같은 제목의 기타 U&L Q&A뿐만 아니라 모든 세부 정보가 포함되어 있습니다.파이프 버퍼는 얼마나 큽니까?
답변2
읽기는 데이터를 사용할 수 있을 때까지 차단되고, 쓰기는 파이프가 가득 차면 차단되거나 실패합니다. 매개변수가 거의 없습니다.파이프 버퍼,파이프 크기그리고O_비차단파이프라인에서 중요한 역할을 합니다.
PIPE_BUF 값은 'ulimit -a'로 결정할 수 있습니다. 이는limits.h에 정의되어 있습니다. PIPE_BUF는 보장된 크기를 제어합니다.원자 쓰기. 이는 안전한 멀티스레드 애플리케이션을 만드는 데 도움이 됩니다.
PIPE_SIZE는 페이지 크기에 따라 다릅니다. 2.4 커널에서는 페이지 크기(4KB)에 해당합니다. 그러나 2.6 이후 버전은 16페이지(64KB) 배열로 매핑됩니다. 이는 파이프라인_fs_i.h 파일에서 PIPE_BUFFERS(16)로 정의됩니다. 최신 커널에는 페이지 크기를 늘릴 수 있는 fcntl 및 F_SETPIPE_SZ가 있습니다.
O_NONBLOCK은 부분 쓰기와 지연 쓰기를 허용합니다. 그러나 O_NONBLOCK이 활성화되어 있지만 파이프에 쓸 바이트 수가 PIPE_BUF보다 큰 경우 파이프가 가득 차면 쓰기가 실패하고, 그렇지 않으면 반환에 따라 다른 프로세스의 데이터와 혼합됩니다. 쓰기 값이 엇갈렸습니다.
답변3
옵션을 사용해 보세요 -B
. 64k 버퍼만 사용됩니다.
cat /dev/sda1 | less -B
에서 man less
:
-B 또는 --auto-buffers 기본적으로 버퍼는 파이프에서 데이터를 읽을 때 필요에 따라 자동으로 할당됩니다. 파이프에서 많은 양의 데이터를 읽으면 많은 양의 메모리가 할당될 수 있습니다. -B 옵션은 파이프 버퍼의 자동 할당을 비활성화하므로 파이프는 64K(또는 -b 옵션으로 지정된 공간의 양)만 사용합니다. 경고: -B를 사용하면 파일의 가장 최근에 본 부분만 메모리에 보관되므로 이전 데이터가 손실되므로 표시 오류가 발생할 수 있습니다.