child 프로세스에서 파일 디스크립터를 사용하려면?

gnugpl의 이미지

fork 시에 child 프로세스는 부모 프로세스가 오픈한 파일 디스크립터를
상속하는것으로 알고 있습니다.

또한fork후 execl 로 새로운 이미지로 써도, 파일 디스크립터는 상속되는것으로 알고 있습니다.

fork만으로는 같은 코드이므로 파일 디스크립터를 사용할수 있지만,
fork후 execl로 새로운 프로세스를 띄웠을때는 파일 디스크립터를 어떻게 사용해야 하는지요?
가능한건가요?

감사합니다.

shkwon81의 이미지

쉬운 듯 하면서도 난해한 질문이네요..

당연히 자식 프로세스(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처럼 다른 유틸리티들과 쉽게 연동되어
사용될 수 있도록 인터페이스가 구성되어 있는 것을 보실 수 있습니다.

gnugpl의 이미지

a, b는 서로 다른 내용의 코드를 담고 있는 실행파일입니다.

a는 a.cfg 파일을 참조하여 값을 확인하고 있습니다.
b 또한 a.cfg 파일을 참조하여 값을 확인하려 합니다.

특정 목적때문에 둘은 같은 파일 디스크립터를 참조해야 합니다.

a는 Fork를 한후, b를 execl로 로드합니다.

<<하지만 b는 a의 파일 디스크립터를 확인할길이 없습니다.>>

책에는 execl로 로드하여도 child 프로세스는 파일 디스크립터를 상속받는다고 써있습니다.

그렇다면 a와 실행코드가 전혀 다른 child 프로세스는 상속 받은 파일 디스크립터를 어떻게 알수가 있는지요?

감사합니다.

RM -RF /bin

shkwon81의 이미지

답변이 되었었다고 생각했는데..

Quote:
<<하지만 b는 a의 파일 디스크립터를 확인할길이 없습니다.>>

fd를 상속은 받지만, 확인할 길은 없습니다. 그렇기 때문에,
부모, 자식 프로세스 간에 "모종의 규칙"이 필요한 것입니다.

예를 들면, 이런 규칙을 들 수 있겠지요..

"자식 프로세스는 STDIN_FILENO에서 입력을 읽어 들이니까,
여기로 입력을 주고 싶으면 부모 프로세스는 원하는 fd를 STDIN_FILENO
값을 가지도록 한뒤, fork() , exec() 하라."

결과적으로 일반적인 해법으로는 불가능하다고 볼 수 있습니다.
굳이 그런 작업이 필요하시다면, 부모 프로세스가 fork() 전에 해당 fd의
목록을 특정 임시 파일에 써 두고, 그 파일을 자식 프로세스가 읽어서
원하는 fd의 값을 찾아낸다거나 하는 방법을 쓸 수도 있겠지요.

이외에도 방법은 많겠네요.. 그럼 원하는 결과 얻으시길~

stoneshim의 이미지

Quote:
그렇다면 a와 실행코드가 전혀 다른 child 프로세스는 상속 받은 파일 디스크립터를 어떻게 알수가 있는지요?

네... 결국 질문의 핵심이 이건데요.

1. 간단하게.. exec 하면서 fd 번호를 argument로 넘겨줄 수도 있죠.

2. shmkey를 parent-child간에 약속하고 parent가 fd 번호를 공유메모리에 적고 child는 읽어서 처리하기도 합니다.

다른 방법이 또 있을지도 모르겠습니다. 저는 공유메모리를 사용해야 하는 상황이 많아서 대체로 두번째 방법으로 했습니다.

우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자

moonzoo의 이미지

걍 새로 open 하는 것과 어떤 차이가 있나여?

일단 생각으로는.. 어차피 fork()후에 같은 table을 가지므로

execl 할때 인자로 넘겨서 , child에서 그것을 가지고 써도 될듯

한데.. 음..확실한 건 아니구여 --;

걍 떠오르는 생각이었습니다.

새로 open하지 않고 기존걸 써야 하는 이유가 참 궁금하네여.

효율성 때문인가여? 아니면 lock때문일수도 있겠군여..

shkwon81의 이미지

오호~

실행 시에 argument로 넘겨 주는 방법도 있군요.. 그런 간단한 방법이!!
하나 배우고 갑니다..

생각해 보니, getenv(), setenv()를 이용하여 environment로 넘겨 주는
방법.. 기타 등등 편리한 방법이 많네요..

stoneshim의 이미지

Quote:
새로 open하지 않고 기존걸 써야 하는 이유가 참 궁금하네여.

일전에 network server인데 multi-process 구조로 동작하는 프로그램 중에 accept하는 process와 request에 대해 처리하는 process가 서로 다른 실행파일인 경우를 보았습니다.( prefork 구조가 아니라 accept 할 때마다 fork/exec 하는 구조였습니다 )
이 경우에는 accept가 return한 connected fd를 child에게 전달할 필요가 있었죠.

뭐 물론 이 구조가 아주 바람직하다는건 아니지만... 이런 경우라면 사용이 필요하겠죠.

우리 모두 리얼리스트가 되자. 그러나 가슴에 이룰 수 없는 꿈을 가지자

moonzoo의 이미지

아 그런경우라면 필요하겠군여..

답변 감사염..

gnugpl의 이미지

감사합니다.
아규먼트 넘기는 경우는 테스트 해보아야 겠군요.
아규먼트로 받는다는것은 결국 파일 디스크립터 번호만을 받는다는 이야기인데
상속받을시 번호가 동일한 파일 디스크립터에 대한 정보를 가지고 있다는 이야기군요.

RM -RF /bin

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.