도대체 어떻게 전형적인 포탄 "포크 폭탄"이 자신을 두 번 부르나요?

도대체 어떻게 전형적인 포탄 "포크 폭탄"이 자신을 두 번 부르나요?

유명한 것을 경험했다포크 폭탄 문제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를 사용하여 &) 함수를 호출하면 호출된 함수가 반환되기 전에 피호출자가 종료되기 때문에 실제로 포크 폭탄 속도가 느려집니다.

관련 정보