당연히 자식 프로세스(fork -> exec) 에서는 fd 를 사용하여 코딩이
되어 있을 겁니다. 따라서, 부모 프로세스로부터 상속받은 파일
디스크립터 번호가 그대로 자식 프로세스에게 물려지게 됩니다.
따라서, 모종의 약속이 필요하게 됩니다. 예를 들어 pipe 를 예로 들면
ls -l | grep "gondo"
위와 같은 작업에서,
grep은 기본적으로 STDIN_FILENO 에서 입력을 받아 들입니다.
이때, 쉘에서 pipe를 이용하여 ls의 결과를 STDIN_FILENO로 매핑시키고
fork() 를 수행한 후, grep 를 실행(exec)합니다. 따라서 원래 표준
입력에서 입력을 받기로 가정한 grep은 pipe 로부터 입력을 받아 들이게
됩니다.
이게, exec 후에 부모로부터의 fd를 사용하는 일반적인 예입니다.
위에서 grep 유틸리티의 원래 의도가 표준 입력에서 입력을 받아들이는
것이라고는 생각하지 않습니다. 혹시라도 grep을 실행해서 키보드로
부터의 입력을 필터링하고 싶은 사람이 있을까요? 그보다 오히려 grep은
명시적인 파일을 지정하지 않은 경우, pipe를 통한 사용을 "의도"한
것입니다. 그런 이유로, 명시적인 검색 파일을 지정하지 않은 경우,
stdin으로부터의 입력을 걸러낸다고 가정해 놓은 것입니다.
이렇게, exec 된 후에 실행되기를 "의도"한 프로그램은 적어도 해당
프로세스를 fork하고 exec할 부모 프로세스와 모종의 "규칙"을 가지고
있어야 합니다. 위에서 쉘과 grep의 예처럼 말이죠..
유닉스의 기본 철학은 "작은 것이 아름답다" 입니다. 유닉스의 표준
유틸리티들을 살펴 보면, grep처럼 다른 유틸리티들과 쉽게 연동되어
사용될 수 있도록 인터페이스가 구성되어 있는 것을 보실 수 있습니다.
fd를 상속은 받지만, 확인할 길은 없습니다. 그렇기 때문에,
부모, 자식 프로세스 간에 "모종의 규칙"이 필요한 것입니다.
예를 들면, 이런 규칙을 들 수 있겠지요..
"자식 프로세스는 STDIN_FILENO에서 입력을 읽어 들이니까,
여기로 입력을 주고 싶으면 부모 프로세스는 원하는 fd를 STDIN_FILENO
값을 가지도록 한뒤, fork() , exec() 하라."
결과적으로 일반적인 해법으로는 불가능하다고 볼 수 있습니다.
굳이 그런 작업이 필요하시다면, 부모 프로세스가 fork() 전에 해당 fd의
목록을 특정 임시 파일에 써 두고, 그 파일을 자식 프로세스가 읽어서
원하는 fd의 값을 찾아낸다거나 하는 방법을 쓸 수도 있겠지요.
일전에 network server인데 multi-process 구조로 동작하는 프로그램 중에 accept하는 process와 request에 대해 처리하는 process가 서로 다른 실행파일인 경우를 보았습니다.( prefork 구조가 아니라 accept 할 때마다 fork/exec 하는 구조였습니다 )
이 경우에는 accept가 return한 connected fd를 child에게 전달할 필요가 있었죠.
쉬운 듯 하면서도 난해한 질문이네요..당연히 자식 프로세스(for
쉬운 듯 하면서도 난해한 질문이네요..
당연히 자식 프로세스(fork -> exec) 에서는 fd 를 사용하여 코딩이
되어 있을 겁니다. 따라서, 부모 프로세스로부터 상속받은 파일
디스크립터 번호가 그대로 자식 프로세스에게 물려지게 됩니다.
따라서, 모종의 약속이 필요하게 됩니다. 예를 들어 pipe 를 예로 들면
ls -l | grep "gondo"
위와 같은 작업에서,
grep은 기본적으로 STDIN_FILENO 에서 입력을 받아 들입니다.
이때, 쉘에서 pipe를 이용하여 ls의 결과를 STDIN_FILENO로 매핑시키고
fork() 를 수행한 후, grep 를 실행(exec)합니다. 따라서 원래 표준
입력에서 입력을 받기로 가정한 grep은 pipe 로부터 입력을 받아 들이게
됩니다.
이게, exec 후에 부모로부터의 fd를 사용하는 일반적인 예입니다.
위에서 grep 유틸리티의 원래 의도가 표준 입력에서 입력을 받아들이는
것이라고는 생각하지 않습니다. 혹시라도 grep을 실행해서 키보드로
부터의 입력을 필터링하고 싶은 사람이 있을까요? 그보다 오히려 grep은
명시적인 파일을 지정하지 않은 경우, pipe를 통한 사용을 "의도"한
것입니다. 그런 이유로, 명시적인 검색 파일을 지정하지 않은 경우,
stdin으로부터의 입력을 걸러낸다고 가정해 놓은 것입니다.
이렇게, exec 된 후에 실행되기를 "의도"한 프로그램은 적어도 해당
프로세스를 fork하고 exec할 부모 프로세스와 모종의 "규칙"을 가지고
있어야 합니다. 위에서 쉘과 grep의 예처럼 말이죠..
유닉스의 기본 철학은 "작은 것이 아름답다" 입니다. 유닉스의 표준
유틸리티들을 살펴 보면, grep처럼 다른 유틸리티들과 쉽게 연동되어
사용될 수 있도록 인터페이스가 구성되어 있는 것을 보실 수 있습니다.
다른 식으로 질문해보겠습니다.
a, b는 서로 다른 내용의 코드를 담고 있는 실행파일입니다.
a는 a.cfg 파일을 참조하여 값을 확인하고 있습니다.
b 또한 a.cfg 파일을 참조하여 값을 확인하려 합니다.
특정 목적때문에 둘은 같은 파일 디스크립터를 참조해야 합니다.
a는 Fork를 한후, b를 execl로 로드합니다.
<<하지만 b는 a의 파일 디스크립터를 확인할길이 없습니다.>>
책에는 execl로 로드하여도 child 프로세스는 파일 디스크립터를 상속받는다고 써있습니다.
그렇다면 a와 실행코드가 전혀 다른 child 프로세스는 상속 받은 파일 디스크립터를 어떻게 알수가 있는지요?
감사합니다.
RM -RF /bin
답변이 되었었다고 생각했는데..[quote]<<하지만
답변이 되었었다고 생각했는데..
fd를 상속은 받지만, 확인할 길은 없습니다. 그렇기 때문에,
부모, 자식 프로세스 간에 "모종의 규칙"이 필요한 것입니다.
예를 들면, 이런 규칙을 들 수 있겠지요..
"자식 프로세스는 STDIN_FILENO에서 입력을 읽어 들이니까,
여기로 입력을 주고 싶으면 부모 프로세스는 원하는 fd를 STDIN_FILENO
값을 가지도록 한뒤, fork() , exec() 하라."
결과적으로 일반적인 해법으로는 불가능하다고 볼 수 있습니다.
굳이 그런 작업이 필요하시다면, 부모 프로세스가 fork() 전에 해당 fd의
목록을 특정 임시 파일에 써 두고, 그 파일을 자식 프로세스가 읽어서
원하는 fd의 값을 찾아낸다거나 하는 방법을 쓸 수도 있겠지요.
이외에도 방법은 많겠네요.. 그럼 원하는 결과 얻으시길~
[quote]그렇다면 a와 실행코드가 전혀 다른 child 프로세스는 상
네... 결국 질문의 핵심이 이건데요.
1. 간단하게.. exec 하면서 fd 번호를 argument로 넘겨줄 수도 있죠.
2. shmkey를 parent-child간에 약속하고 parent가 fd 번호를 공유메모리에 적고 child는 읽어서 처리하기도 합니다.
다른 방법이 또 있을지도 모르겠습니다. 저는 공유메모리를 사용해야 하는 상황이 많아서 대체로 두번째 방법으로 했습니다.
우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자
굳이 같은 fd를 공유할 필요가 있나여?
걍 새로 open 하는 것과 어떤 차이가 있나여?
일단 생각으로는.. 어차피 fork()후에 같은 table을 가지므로
execl 할때 인자로 넘겨서 , child에서 그것을 가지고 써도 될듯
한데.. 음..확실한 건 아니구여 --;
걍 떠오르는 생각이었습니다.
새로 open하지 않고 기존걸 써야 하는 이유가 참 궁금하네여.
효율성 때문인가여? 아니면 lock때문일수도 있겠군여..
오호~실행 시에 argument로 넘겨 주는 방법도 있군요.. 그
오호~
실행 시에 argument로 넘겨 주는 방법도 있군요.. 그런 간단한 방법이!!
하나 배우고 갑니다..
생각해 보니, getenv(), setenv()를 이용하여 environment로 넘겨 주는
방법.. 기타 등등 편리한 방법이 많네요..
[quote]새로 open하지 않고 기존걸 써야 하는 이유가 참 궁금하네
일전에 network server인데 multi-process 구조로 동작하는 프로그램 중에 accept하는 process와 request에 대해 처리하는 process가 서로 다른 실행파일인 경우를 보았습니다.( prefork 구조가 아니라 accept 할 때마다 fork/exec 하는 구조였습니다 )
이 경우에는 accept가 return한 connected fd를 child에게 전달할 필요가 있었죠.
뭐 물론 이 구조가 아주 바람직하다는건 아니지만... 이런 경우라면 사용이 필요하겠죠.
우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자
그렇군여..
아 그런경우라면 필요하겠군여..
답변 감사염..
감사합니다.
감사합니다.
아규먼트 넘기는 경우는 테스트 해보아야 겠군요.
아규먼트로 받는다는것은 결국 파일 디스크립터 번호만을 받는다는 이야기인데
상속받을시 번호가 동일한 파일 디스크립터에 대한 정보를 가지고 있다는 이야기군요.
RM -RF /bin
댓글 달기