Bash 명명된 파이프 - 원자 읽기

Bash 명명된 파이프 - 원자 읽기

명명된 파이프에 쓸 스크립트 하나를 설정한 다음 명명된 파이프에서 읽을 스크립트 4개를 설정했습니다.

대부분의 항목에는 문제가 없지만 입력 줄에 대한 처리가 거의 수행되지 않으면 일부 읽기가 서로 충돌하기 시작하고 결과 텍스트는 최대 4줄 처리에 대한 임의 문자의 조합입니다.

xargs 또는 병렬 처리를 사용할 수 없는 이유는 데이터베이스에 연결하는 데 1초가 걸리기 때문입니다. 이는 일반적으로 처리하는 데 최대 약 1300행을 추가합니다.

예제 출력:

MAIN.MK37의 Runstats가 1초 만에 완료됨: DB20000I RUNSTATS 명령이 성공적으로 완료되었습니다.

MAIN.MKAP의 Runstats가 0초 안에 완료됨: DB20000I RUNSTATS 명령이 성공적으로 완료되었습니다.

MAIN.MKAL의 Runstats가 0초 안에 완료됨: DB20000I RUNSTATS 명령이 성공적으로 완료되었습니다.

MAIN.MK49의 Runstats가 0초 안에 완료됨: DB20000I RUNSTATS 명령이 성공적으로 완료되었습니다.

0초 후에 AI.K1MAIN에 대한 통계 실행이 실패했습니다. SQL2306N 테이블 또는 인덱스 'AI.K1MAIN'이 존재하지 않습니다.

MNM5에서 Runstat가 실패합니다. 0 이후: SQL0104N 예상치 못한 태그 'MNM5'. "TBLE" 다음에 발견되었습니다. 예상 태그에는 ""가 포함될 수 있습니다. SQL 상태=42601

MAIN.MK50의 Runstats가 0초 안에 완료됨: DB20000I RUNSTATS 명령이 성공적으로 완료되었습니다.

MAIN.MK52의 Runstats가 0초 안에 완료됨: DB20000I RUNSTATS 명령이 성공적으로 완료되었습니다.

작가:

# Open pipe for writing
exec 10>"${PIPE_LOCATION}"

# Feed data
while read LINE; do
    echo "${LINE}" >&10
done <<< "${LIST}"

# Tell threads to stop
i=0
while [ "${i}" -lt 4 ]; do
    echo "stop" >&10
    (( i += 1 ))
done

# Close pipe
exec 10>&-

리더:

# Open Pipe
exec 10<"${PIPE_LOCATION}"

while read -u 10 -r SCHEMA TABLE; do
    if [[ "${SCHEMA}" == 'stop' ]]; then
        break
    fi

    #
    # Runstats Code Here
    #

done

# Close Pipe
exec 10<&-

읽기를 원자적으로 만드는 방법이 있나요?

나는 서버처럼 메인 스레드를 조정하고 입력이 필요할 때마다 4명의 독자가 요청을 보내도록 할 수 있다고 생각합니다. 그러면 문제가 해결될 수 있습니다(그래도 1개가 아닌 5개의 파이프!). 더 간단한 해결책을 제안할 수 있습니다. 저는 모두 귀를 기울이고 있습니다!

답변1

@MarkPlotnick의 생각이 맞습니다. 행을 공백으로 채우고 고정 크기 레코드를 사용하여 읽기 위해 스크립트를 변경했습니다.

참고: @Hauke ​​​​Laging이 발견한 대로 파일 설명자는 이제 10이 아닌 5입니다.

이제 다음과 같이 데이터를 제공하고 있습니다.

# Feed data
while read LINE; do
    printf "%64s" "${LINE}" >&5
done <<< "${LIST}"

다음과 같이 읽으세요:

while read -u 5 -N 64 -r LINE; do
    LINE=(${LINE})
    SCHEMA=${LINE[0]}
    TABLE=${LINE[1]}

그리고 더 이상 오류가 없습니다!

관련 정보