깨진 파이프! 명명된 파이프를 사용하여 두 개의 독립적인 프로그램을 함께 연결하는 문제

깨진 파이프! 명명된 파이프를 사용하여 두 개의 독립적인 프로그램을 함께 연결하는 문제

나는 일반적으로 Linux 시스템에서 직렬로 실행하는 두 개의 명령줄 프로그램을 가지고 있습니다.

이 두 프로그램의 일반적인 실행은 다음과 같습니다.

  1. 프로그램 A가 실행됩니다. 간단한 텍스트 파일을 가져와서 간단한 텍스트 파일을 출력합니다.
  2. 프로그램 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 스크립트를 작성했습니다.

  1. 두 프로그램을 연결하는 명명된 파이프를 만듭니다. 이름을 dataOut.pipe로 지정하세요.
  2. 프로그램 A는 평소처럼 텍스트 파일을 읽지만 이전처럼 텍스트 파일에 쓰는 대신 1단계에서 생성된 파이프 dataOut.pipe에 씁니다.
  3. 프로그램 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가 끝날 때)에만 처리를 시작하기 때문입니다.

관련 정보