존재하다이 페이지~에서4.4 BSD 운영 체제의 설계 및 구현, 그것은 말한다 :
파이프와 소켓의 주요 차이점은 파이프에는 통신 채널을 설정하기 위해 공통 상위 프로세스가 필요하다는 것입니다.
그러나 올바르게 문서화했다면 새로운 프로세스를 생성하는 유일한 방법은 fork
기존 프로세스를 생성하는 것입니다. 그래서 저는 어떻게 두 프로세스가 공통 조상을 가질 수 없는지 이해하지 못합니다. 그렇다면 모든 프로세스 쌍이 파이프를 통해 서로 연결될 수 있다는 것이 맞습니까?
답변1
그렇다면 모든 프로세스 쌍이 파이프를 통해 서로 연결될 수 있다는 것이 맞습니까?
설마.
파이프는 상위 프로세스에 의해 설정되어야 합니다.앞으로하나 이상의 자식이 포크됩니다. 하위 프로세스가 분기되면 해당 파일 설명자는 "외부에서"(디버거 등 무시) 조작할 수 없으며 상위 프로세스(또는 다른 프로세스)는 사실 이후에 "comms.channel 설정" 부분을 수행할 수 없습니다.
따라서 이미 실행 중인 두 개의 임의 프로세스를 사용하는 경우 이들 사이에 파이프를 직접 설정할 수 없습니다. 통신을 허용하려면 어떤 형태의 소켓(또는 다른 IPC 메커니즘)을 사용해야 합니다. (그러나 일부 운영 체제(그 중 FreeBSD)에서는 Unix 도메인 소켓에서 파일 설명자를 보낼 수 있습니다.)
답변2
이 문장은 그다지 명확하지 않습니다. 첫 번째,부모~해야 한다선조, 파이프를 설정하는 프로세스는 상위 프로세스, 조부모, 증조부... 조부모 또는 통신 프로세스 중 하나일 수 있기 때문입니다. 둘째, 이 문장의 의미는 "파이프를 원하면 공통 조상 프로세스가 있어야 한다"는 것이 아니라, "파이프를 원하면 이를 설정하는 공통 조상 프로세스가 있어야 한다"는 것입니다.
내부적으로 프로세스는 자체적으로 파이프를 설정합니다. 파이프는 다른 파일 설명자와 같은 파일 설명자이거나 더 정확하게는 양쪽 끝에 하나씩 있는 파일 설명자 쌍입니다. 파이프를 생성한 프로세스는 파이프를 즉시 사용하여 자신에게 데이터를 보낼 수 있지만 이는 거의 유용하지 않습니다.자기 관리용도가 있습니다.)
일반적인 관용구는 프로세스가 파이프를 설정한 다음 하위 프로세스를 분기하고 상위 프로세스에서 파이프의 한쪽 끝을 닫고 하위 프로세스에서 파이프의 다른 쪽 끝을 닫는 것입니다. 이를 통해 상위 프로세스와 하위 프로세스가 한 방향으로 통신할 수 있습니다. 프로세스에 양방향 통신이 필요한 경우 두 개의 파이프가 필요합니다(파이프가 양방향인 일부 UNIX 변형 제외).
파이프는 하위 프로세스에 의해 상속되므로 파이프를 생성한 프로세스는 통신에 참여하지 않을 수 있습니다. 예를 들어 두 개의 외부 명령 사이에 생성된 셸의 파이프라인에는 ls | rot13
다음 단계가 포함됩니다.
- 쉘은 파이프를 생성합니다.
- 쉘은 프로세스를 분기합니다. 하위 프로세스는 파이프의 읽기 끝을 닫고
execve
를 호출합니다ls
. - 쉘은 프로세스를 분기합니다. 하위 프로세스는 파이프의 쓰기 끝을 닫고
execve
를 호출합니다rot13
. - 쉘은 파이프의 양쪽 끝을 닫고 두 하위 프로세스가 모두 종료될 때까지 기다립니다.
두 개의 기존 프로세스가 서로 통신하려는 경우 다음을 사용할 수 있습니다.명명된 파이프. (글쎄, 그것도 있어파일 설명자 전달, 하지만 마음이 약한 사람에게는 적합하지 않습니다. )
답변3
파이프의 쉘은 파이프의 여러 구성원 간에 통신 채널을 설정하는 공통 상위입니다.
모든 프로세스는 다른 프로세스로 파이프될 수 있습니다. 유일한 프로세스유용할 수 있다표준 입력에서 읽고 표준 출력에 쓰는 "필터"가 함께 파이프로 연결됩니다.
예를 들어, 다음 명령을 실행하면
$ tail -f /etc/motd | tail -f | cat > /dev/null
ps -eaH
호출 쉘의 자식으로 고양이와 고양이의 두 꼬리를 표시합니다.
1675 pts/0 00:00:00 bash
2483 pts/0 00:00:00 tail
2484 pts/0 00:00:00 tail
2485 pts/0 00:00:00 cat