리눅스에서 파이프를 닫아야 하는 이유는 무엇입니까?
프로세스 프로세스 통신에 파이프를 사용할 때 파이프의 한쪽 끝을 닫는 목적은 무엇입니까?
예:파이프를 사용하여 두 프로그램 사이에 간단한 문자열을 보내는 방법은 무엇입니까?
하위 및 상위 프로세스에서 파이프의 한쪽이 닫혀 있습니다.이것이 필요한 이유는 무엇입니까?
파이프를 사용하여 두 공정(상위 및 하위)을 연결하는 경우 포크 앞에 파이프를 만듭니다.
포크는 두 공정이 파이프의 양쪽 끝에 액세스할 수 있도록 합니다.이것은 바람직하지 않습니다.
독서측은 EOF 조건을 발견하면 글쓴이가 끝냈다는 것을 배우게 되어 있습니다.이것은 모든 쓰기 영역이 닫혀 있는 경우에만 발생할 수 있습니다.따라서 가능한 한 빨리 작성 FD를 종료하는 것이 가장 좋습니다.
작성기는 너무 많은 FD가 열려 있지 않도록 판독 FD를 닫아야 하며, 따라서 기존의 개방 FD 한계에 도달할 수 있습니다.게다가, 당시 독자만 사망한 경우, 작성자는 SIGPIPE 또는 적어도 EPIPE 오류(신호가 정의되는 방식에 따라 다름)를 얻음으로써 이에 대한 알림을 받습니다.만약 독자가 여러 명이라면, 작가는 "진짜"가 사라지고, 쓰기를 계속하고, 쓰기 FD가 희망을 차단하면서 막히게 된다는 것을 감지할 수 없으며, "사용되지 않는" 독자는 무언가를 읽을 것입니다.
다음은 무슨 일이 일어나는지 자세히 보여줍니다.
- 호출 상위프스출
pipe()
그리고 2개의 파일 설명자를 가져옵니다.rd
그리고.wr
. - 호출 상위프스출
fork()
이제 두 프로세스 모두 다음과 같은 특징을 가지고 있습니다.rd
a 리고a.wr
. 하위 프로세스가 판독기라고 가정합니다.
그리고나서
- 부모는 (FD를 낭비하지 않고 죽어가는 판독기를 적절하게 감지하기 위해) 판독 끝을 닫아야 합니다.
- EOF 조건을 감지할 수 있으려면 어린이가 쓰기 끝을 닫아야 합니다.
지정된 시간에 열 수 있는 파일 설명자의 수는 제한되어 있습니다.파이프를 계속 열다가 곧 닫지 않으면 FD가 부족해지고 더 이상 아무것도 열 수 없습니다. 파이프도, 파일도, 소켓도...
파이프를 닫는 것이 중요할 수 있는 또 다른 이유는 닫는 것 자체가 응용 프로그램에 의미가 있을 때입니다.를 들어,는 " 예들어의, 파프인용일같다다습니음과도는적"를 보내는 것입니다.errno
할 때 합니다.fork
그리고.exec
외부 프로그램 시작하기
- , " 부가파를만호다들니출합고이프모다,니▁calls호▁the"라고 부릅니다.
fork
하위 프로세스를 만들고 해당 쓰기 끝을 닫은 후 파이프에서 읽으려고 합니다. - 는 하위프스가시사다니합도를 .
exec
다른 프로그램 실행하기- 한다면
exec
예를 들어 프로그램이 존재하지 않기 때문에 실패합니다.errno
파이프에 연결하면 부모는 파이프를 읽고 무엇이 잘못되었는지 알고 사용자에게 말할 수 있습니다. - 한다면
exec
파이프가 아무 것도 기록되지 않고 닫힙니다. 그read
부모의 함수는 파이프가 닫혔음을 나타내는 0을 반환하고 프로그램이 성공적으로 시작되었음을 알립니다.
- 한다면
만약 부모가 파이프에서 읽기 전에 파이프의 쓰기 끝을 닫지 않았다면, 이것은 작동하지 않을 것입니다. 왜냐하면read
다음 시간에 함수가 반환되지 않습니다.exec
성공했습니다.
사용하지 않는 파이프 파일 설명자를 닫는 것은 프로세스가 제한된 파일 설명자 집합을 소진하지 않도록 하는 것 이상의 문제입니다. 파이프를 올바르게 사용하는 데 필수적입니다.이제 파이프의 읽기 및 쓰기 끝 모두에 대해 사용되지 않는 파일 설명자를 닫아야 하는 이유를 고려합니다.파이프에서 읽는 프로세스는 파이프에 대한 쓰기 설명자를 닫으므로 다른 프로세스가 출력을 완료하고 쓰기 설명자를 닫으면 읽기에서 파일 끝이 표시됩니다(파이프에서 미결 데이터가 준비되면).읽기 프로세스가 파이프의 쓰기 끝을 닫지 않으면 다른 프로세스가 쓰기 설명자를 닫은 후에도 파이프에서 모든 데이터를 읽은 후에도 파일 끝이 표시되지 않습니다. 신에대, a.read()
커널이 파이프에 대해 열려 있는 쓰기 설명자가 하나 이상 있다는 것을 알고 있기 때문에 데이터 대기를 차단합니다.이 설명자가 판독 프로세스 자체에 의해 열린 상태로 유지된다는 것은 관련이 없습니다. 이론적으로 이 프로세스는 판독 시도가 차단되더라도 파이프에 기록될 수 있습니다.를 들면, 를들어예,,read()
파이프에 데이터를 쓰는 신호 처리기에 의해 중단될 수 있습니다.쓰기 프로세스가 다른 이유로 인해 파이프에 대한 읽기 설명자를 닫습니다.설명자가 은 프세스열있읽설가프없명진가는로다파전쓰니다합송음하을커널은면을 .SIGPIPE
쓰기 과정에 신호를 보냅니다.기본적으로 이 신호는 프로세스를 종료합니다. 이할 수 . 이 "" " " " " " " " " " " 는 신호를 잡습니다."write()
하여 오류가 합니다.EPIPE
(깨진 파이프).의 SIGPIPE
신호를 보내거나.EPIPE
에 대해 이며, 에 대해 읽기 하는 입니다. error는 파이프에 대해 사용되지 않는 읽기 설명자입니다.쓰기 프로세스가 파이프의 읽기 끝을 닫지 않으면 다른 프로세스가 파이프의 읽기 끝을 닫은 후에도 쓰기 프로세스가 파이프를 채우고 더 이상 쓰기 시도는 무기한 차단됩니다.사용하지 않는 파일 설명자를 닫는 마지막 이유는 모든 파일 설명자가 닫힌 후에만 파이프가 파괴되고 다른 프로세스에서 재사용하기 위해 해당 리소스가 해제되기 때문입니다.이 시점에서 파이프의 읽지 않은 데이터는 손실됩니다.
Michael Kerrisk, 리눅스 프로그래밍 인터페이스
언급URL : https://stackoverflow.com/questions/19265191/why-should-you-close-a-pipe-in-linux
'programing' 카테고리의 다른 글
MongoDB 스토리지 크기 제한? (0) | 2023.07.14 |
---|---|
하위 프로세스가 종료될 때까지 기다리는 방법 (0) | 2023.07.14 |
애니메이션 DidStop에서 CA 애니메이션을 식별하는 방법은 무엇입니까? (0) | 2023.07.14 |
"ORA-01008: 일부 변수가 바인딩되지 않음" 오류 (0) | 2023.07.14 |
.NET 응용 프로그램에서는 SQL 쿼리가 느리지만 SQL Server Management Studio에서는 즉시 실행됨 (0) | 2023.07.14 |