동시에 여러개의 프로세스에서 같은 소켓에 대해서 select() 할

syan의 이미지

소켓을 listen()까지 작업을 해서 생성한 후에 fork()로 자식 프로세스를 만들고요.
이 자식프로세스들이 모두 이 소켓을 select() 셋에 집어넣고 select() 상태에서 대기하게 하면요.

클라이언트가 요청할 때 이들 프로세스 중 하나만 감지해서 accept() 처리가 될까요?

아니면 모든 프로세스가 다 감지하는 지 아니면 아예 감지를 못하는 지... 혹시 아예 말도 안되는 것은 아닌지 궁금하네요. ^^;

김충길의 이미지

accept는 하나만 됩니다.

pre-fork 방식이 다 저렇게 사용합니다.

screen + vim + ctags 좋아요~

pynoos의 이미지

syan wrote:
소켓을 listen()까지 작업을 해서 생성한 후에 fork()로 자식 프로세스를 만들고요.
이 자식프로세스들이 모두 이 소켓을 select() 셋에 집어넣고 select() 상태에서 대기하게 하면요.

클라이언트가 요청할 때 이들 프로세스 중 하나만 감지해서 accept() 처리가 될까요?

아니면 모든 프로세스가 다 감지하는 지 아니면 아예 감지를 못하는 지... 혹시 아예 말도 안되는 것은 아닌지 궁금하네요. ^^;

또한, select 는 모든 자식에게서 되며, 그중 먼저 accept하는 process만 진행을 계속할 테니, 다른 프로세스는 accept에서 block 되어 있을 것입니다.

semaphore 등을 사이에 두어, 한녀석만 select 하게 만든다는지, 아니면, select를 모두 빼버리고, semaphore를 lock한 녀석만, accept에서 block 되게 만들면 됩니다.

김충길의 이미지

구지 세마포어를 사용하지 않고 해도 됩니다.
어짜피 accept는 한 녀석만 됩니다. fcntl 로 넌 블러킹으로 만든
다음 select , accept를 사용하세요.

pynoos wrote:
syan wrote:
소켓을 listen()까지 작업을 해서 생성한 후에 fork()로 자식 프로세스를 만들고요.
이 자식프로세스들이 모두 이 소켓을 select() 셋에 집어넣고 select() 상태에서 대기하게 하면요.

클라이언트가 요청할 때 이들 프로세스 중 하나만 감지해서 accept() 처리가 될까요?

아니면 모든 프로세스가 다 감지하는 지 아니면 아예 감지를 못하는 지... 혹시 아예 말도 안되는 것은 아닌지 궁금하네요. ^^;

또한, select 는 모든 자식에게서 되며, 그중 먼저 accept하는 process만 진행을 계속할 테니, 다른 프로세스는 accept에서 block 되어 있을 것입니다.

semaphore 등을 사이에 두어, 한녀석만 select 하게 만든다는지, 아니면, select를 모두 빼버리고, semaphore를 lock한 녀석만, accept에서 block 되게 만들면 됩니다.

screen + vim + ctags 좋아요~

stoneshim의 이미지

제가 알기로는 대부분의 OS가 여러 프로세스가 동시에 하나의 socket에 accept() 시도하는 경우에 mutual exclusion을 제공하는 것으로 알고 있습니다.

하지만 이러한 mutual exclution을 제공하지 않는 OS를 위해서( 실제로 어떤 OS의 version인지는 모릅니다. ) 라면 application level에서 locking을 해주어야 할 것입니다.

대표적인 preforked model인 apache도 child 프로세스들이 accept()를 호출하기 이전에 record locking을 사용합니다.

child 프로세스들이 동시에 하나의 socket에 대해 select()를 호출하고, 해당 fd가 readable 한 경우에는 모든 child 프로세스에게 readable 함을 알려주므로, preforked model에서 굳이 사용할 필요가 있나 싶습니다.

첨언하여 multi-thread 의 경우에 여러 thread에서 동일 fd에 대해 select나 poll을 호출하면 하나의 thread에게만 event를 전달해 줍니다.
이와는 다르게, epoll의 경우에는 모든 thread에게 event가 전달됩니다.

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

pynoos의 이미지

semaphore를 사용할 때의 이점은, 현재 몇 개나 되는 process가 idle 한지 알아 보는데 유용합니다.
prefork 는 fork 개수를 미리 만들어 놓기 때문에, 기다리는 프로세스를 알 수 없으면, 한녀석도 accept 에 대기하지 않는 상황이 발생합니다.

저는 apache 가 semaphore만 사용하는 줄 알았는데, stoneshim님의 말을 듣고 다시 소스를 보니, OS 마다 다른 것을 사용하더군요.

김충길의 이미지

apache 의 경우 대기 프로세스를 따로 관리 하지 않나요?
세마포어로만 한다면 몇개인지를 알 수 있겠으나.. 가변적으로
증가시키거나 감소시키기에는 불편하지 않을까요.

screen + vim + ctags 좋아요~

choissi의 이미지

아파치는 다른 이유때문에 accept serialize를 합니다.

아파치가 하나의 소켓만 바인드 하는게 아니라
설정에 따라 여러 소켓으로 바인딩을 할수가 있죠..

문제는 여기서 시작되는데,
자식 프로세스에서 select걸어 두고 기다리고 있을때
접속 요청이 들어 오면 모두 select가 풀리게 되고
그중에 한녀석만, accept가 되고 나머진 블럭이 걸리겠죠.

그렇게 되면 처음 요청과 다른 포트로 요청이 들어오는 것을
받을 수가 없게 됩니다.

또, 그 시리얼라이즈 하는 방법들도 선택할수 있는데
요런게 가능합니다.

HAVE_FLOCK_SERIALIZED_ACCEPT
HAVE_FCNTL_SERIALIZED_ACCEPT
HAVE_SYSVSEM_SERIALIZED_ACCEPT
HAVE_USLOCK_SERIALIZED_ACCEPT
HAVE_PTHREAD_SERIALIZED_ACCEPT

더 궁금하시만 아래의 링크를 참조하세요

http://www.ezdoum.com/stories.php?story=02/08/17/3254153

ps. 아파치는 대기프로세스 관리등을 스코어보드란 파일에 기록합니다.

울랄라~ 호기심 천국~!!
http://www.ezdoum.com

pynoos의 이미지

apache 는 물론 세마포어로 대기 프로세스를 관리하지 않습니다. 그놈은 semaphore 말고도 다른 locking 을 사용하도록 돼있던데.. (지금보니까.. ^^) 그방법을 사용하지 않겠지요.

저도 간단히 만들때는 아무 locking도 안쓰고 경쟁적으로 accept하도록 합니다.

귀찮은 문제죠. min/max 정해서 가변적으로 대기하게 만드는 문제.. 불편하고...

뭐 답이 있겠습니까... 훌륭한 소스보고 참고하면.. 감탄할 따름이지요..

------

올리고보니... 최씨님께서 좋은 글을 올려주셨군요.. (참고로 저도 최씨입니다.. ^^)

저도 pre-fork / semaphore 조합을 선택해야했던 이유가 multiple port 를 accept하는 문제 때문이었던 것 같습니다. 안쓰면 녹습니다.. --`

맹고이의 이미지

pynoos wrote:
올리고보니... 최씨님께서 좋은 글을 올려주셨군요.. (참고로 저도 최씨입니다.. ^^)

제가 왈가왈부할 입장이 아니겠습니다만...

choissi님은 최씨가 아니에요~ =3=3=3

syan의 이미지

답변 감사합니다. 풍성한 추석 되시길... :lol:

DTSTTCPW

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.