유명한 것을 경험했다포크 폭탄 문제Askubuntu와 다른 많은 Stack Exchange 사이트에서는 너무 뻔하기 때문에 모든 사람이 말하는 내용을 잘 이해하지 못합니다.
많은 답변 (가장 좋은 예) 이렇게 말합니다.
"는
{:|: &}
함수를 실행:
하고 출력을:
함수에 다시 보내는 것을 의미합니다."
훌륭한,정확히 뭐야?출력은 :
? 상대방에게 어떤 내용이 전달되고 있나요 :
?
그리고:
본질적으로 자신을 호출하는 함수를 생성하고 있습니다.두 배호출할 때마다 자체적으로 종료되는 메서드는 없습니다.
어떻게 구현되나요?두 배? 제가 보기엔 :
첫 번째 실행이 완료될 :
때까지 두 번째 실행에는 아무 것도 전달되지 않는 것 같습니다 . 실행은 실제로 끝나지 않습니다.
예를 들어 C
,
foo()
{
foo();
foo(); // never executed
}
두 번째 것은 foo()
전혀 실행되지 않습니다. 단순히 첫 번째가 foo()
끝나지 않기 때문입니다.
나는 동일한 논리가 적용된다고 생각합니다 :(){ :|: & };:
.
:(){ : & };:
같은 일을 해라
:(){ :|: & };:
논리를 이해하도록 도와주세요.
답변1
파이프라인에서는 다른 인스턴스를 시작하기 전에 첫 번째 인스턴스를 완료할 필요가 없습니다. 실제로 하는 일은 리디렉션뿐입니다.표준 출력첫 번째 사례표준 입력두 번째는 동시에 실행될 수 있도록 하는 것입니다(포크 폭탄이 작동해야 하기 때문입니다).
그렇다면 의 출력은 정확히 무엇입니까
:
? 상대방에게 무엇이 전달되고 있습니까:
?
':'는 다른 ':' 인스턴스에 아무것도 쓰지 않고 리디렉션만 합니다.표준 출력도착하다표준 입력의 두 번째 인스턴스입니다.만약에실행 중에 무언가를 쓰고(자체 포크만 수행하기 때문에 절대 수행하지 않음) 다음으로 이동합니다.표준 입력또 다른 사례.
상상하는 데 도움이 된다표준 입력그리고표준 출력무리로서:
뭐라고 쓰여져 있어도표준 입력프로그램이 읽기로 결정할 때 사용하기 위해 스택됩니다.표준 출력동일한 방식으로 작동합니다. 필요할 때 다른 프로그램이 읽을 수 있도록 여러 개에 기록합니다.
이를 통해 통신이 발생하지 않는 파이프(두 개의 빈 힙) 또는 비동기 쓰기 및 읽기와 같은 상황을 쉽게 상상할 수 있습니다.
정확히 어떻게 두 번 실행됩니까? 제가 보기엔
:
첫 번째 실행이 완료될:
때까지 두 번째 실행에는 아무 것도 전달되지 않는 것 같습니다 . 실행은 실제로 끝나지 않습니다.
인스턴스의 입력과 출력을 리디렉션하는 것이므로 두 번째 인스턴스가 시작되기 전에 첫 번째 인스턴스가 완료될 필요가 없습니다. 실제로는 일반적으로 두 가지가 동시에 실행되어 두 번째가 첫 번째가 즉시 구문 분석하는 데이터를 처리할 수 있기를 원합니다. 이것이 여기서 일어나는 일입니다. 두 가지 모두 첫 번째 작업이 완료될 때까지 기다리지 않고 호출됩니다. 이는 모두에게 적용됩니다.파이프 체인명령줄.
나는 동일한 논리가 :(){ :|: & };: 에도 적용된다고 생각합니다.
:(){ : & };:
같은 일을 해라
:(){ :|: & };:
첫 번째는 함수 자체가 재귀적으로 실행되더라도 백그라운드( : &
) 에서 호출되기 때문에 작동하지 않습니다. 첫 번째 인스턴스는 자체 종료 전에 :
"하위"가 반환될 때까지 기다리지 않으므로 실행 중인 인스턴스가 :
하나만 남을 수 있습니다 :
. 만약 당신이 그것을 갖고 있다면 , 첫 번째는 "자식"이 돌아올 때까지 기다리고 , 자신의 "자식"이 돌아올 때까지 기다릴 것이기 :(){ : };:
때문에 작동할 것입니다 .:
:
:
실행 중인 인스턴스 수에 따른 다양한 명령의 모양은 다음과 같습니다.
:(){ : & };:
1개의 인스턴스(호출 :
및 종료) -> 1개의 인스턴스(호출 :
및 종료) -> 1개의 인스턴스(호출 :
및 종료) -> 1개의 인스턴스 -> ...
:(){ :|: &};:
1개 인스턴스(각각 2를 호출 :
하고 종료) -> 2개 인스턴스(각각 2를 호출 :
하고 종료) -> 4개 인스턴스(각 인스턴스가 2를 호출 :
하고 종료) -> 8개 인스턴스 -> ...
:(){ : };:
1개의 인스턴스(호출 :
하고 반환을 기다리는 중) -> 2개의 인스턴스(자녀가 다른 인스턴스를 호출 :
하고 반환을 기다리는 중) -> 3개의 인스턴스(자녀가 다른 인스턴스를 호출 :
하고 반환을 기다리는 중) -> 4개의 인스턴스 - > . ..
:(){ :|: };:
1개 인스턴스(2개를 호출 :
하고 반환을 기다리는 중) -> 3개 인스턴스( :
각 2개를 호출하고 반환을 기다리는 어린이) -> 7개 인스턴스( :
2개를 호출하고 반환을 기다리는 하위) -> 15개 인스턴스 -> ...
보시다시피, 백그라운드에서 (fork를 사용하여 &
) 함수를 호출하면 호출된 함수가 반환되기 전에 피호출자가 종료되기 때문에 실제로 포크 폭탄 속도가 느려집니다.