나는 일반적으로 Linux 시스템에서 직렬로 실행하는 두 개의 명령줄 프로그램을 가지고 있습니다.
이 두 프로그램의 일반적인 실행은 다음과 같습니다.
- 프로그램 A가 실행됩니다. 간단한 텍스트 파일을 가져와서 간단한 텍스트 파일을 출력합니다.
- 프로그램 B는 A 다음에 실행되며 해당 입력은 프로그램 A에 의해 생성된 텍스트 파일입니다. 또한 간단한 텍스트 파일을 출력합니다.
참고: 위의 두 프로그램의 경우 입력 및 출력은 단순히 해당 입력 및 출력 파일의 경로입니다. 예: $ prog_a /path/to/inputfile/dataIn.txt /path/to/outputfile/dataOut.txt $ prog_b /path/to/inputfile/dataOut.txt /path/to/outputfile/results.txt
이는 타사에서 개발한 프로그램입니다. 따라서 우리는 그것들을 쉽게 수정할 수 없습니다(적어도 시간이 지나면서). 그러나 명명된 파이프를 사용하여 병렬로 실행하여 실행 속도를 높이고 싶습니다. 데이터 파일은 때때로 매우 커서 병렬 처리가 작업 속도를 높일 것이라고 생각했습니다. 저는 본 프로젝트의 과제를 수락하고 다음과 같이 진행하였습니다.
다음과 같은 bash 스크립트를 작성했습니다.
- 두 프로그램을 연결하는 명명된 파이프를 만듭니다. 이름을 dataOut.pipe로 지정하세요.
- 프로그램 A는 평소처럼 텍스트 파일을 읽지만 이전처럼 텍스트 파일에 쓰는 대신 1단계에서 생성된 파이프 dataOut.pipe에 씁니다.
- 프로그램 B는 파이프를 통해 프로그램 A의 출력을 읽습니다.
Bash 스크립트는 다음과 같습니다:
\#!/bin/bash
mkfifo dataOut.pipe
prog_b dataOut.pipe results.txt &
prog_a dataIn.txt dataOut.pipe
rm dataOut.pipe
이제 이것이 작동합니다... 가끔... stderror에 Java 예외가 발생하는 경우가 많습니다. 문제가 정확히 무엇인지 알 수는 없지만 다음과 같습니다.
프로그램 B가 때때로 A보다 빠르게 실행되고 A가 데이터를 넣을 수 있는 것보다 파이프를 더 빨리 지워서 전체가 충돌할 수 있습니까?
이 경우 간단한 해결책이 있습니까? 아니면 다른 일이 일어나고 있나요?
답변1
깨진 파이프는 작성자(prog_a)가 손상된 파이프에 쓰려고 한다는 의미입니다.폐쇄독자(prog_b)에 의해. prog_b가 왜 그렇게 빨리 중지되었는지 알아낼 만큼 충분한 정보를 제공하지 않았습니다.
즉, prog_b는 EOF가 충족될 때까지 입력 파일을 순차적으로 읽고 일반 Unix 필터 명령과 마찬가지로 각 줄을 읽을 때 처리한다고 가정합니다. 확실합니까? prog_b가 입력 파일을 검색하거나 mmap하려는 경우 실패할 수 있습니다(prog_a도 마찬가지입니다). prog_b가 모든 입력 라인을 읽고 이를 처리하려는 경우 prog_a와 prog_b를 병렬화하면 거의 아무 것도 얻을 수 없습니다. 왜냐하면 prog_b는 파이프라인이 닫힐 때(즉, prog_a가 끝날 때)에만 처리를 시작하기 때문입니다.