pre-fork() + select() or epoll() 질문입니다....

jsh8276의 이미지

안녕하세요... RedHat9 에서 간단한 서버 테스트를 하는중 궁금한 점이
있어서 이렇게 질문 올립니다...

pre-fork()를 통해 서브 프로세스를 3개 생성한 후에 서브 프로세스에서
accept()를 통해 클라이언트의 접속을 처리한 경우에
각각의 서브 프로세스에서 순차적으로 accept() 수행합니다.
그런데 이 서브 프로세스에 select()를 호출하며 다중 클라이언트를 처리
하려고 하면 한 서브 프로세스에서만 accept()를 수행하더군요...

왜 이렇게 되는지 도무지 알 수가 없어서 질문을 드립니다.
미리 감사드리구요 좋은 하루 보내세요...

pynoos의 이미지

pre-fork를 통하여 동시에 listen하는 프로세스가 있다하더래도, accept는 한 녀석만 일어나게 됩니다.

listen port를 select하는 순간은 모든 대기 프로세스가 깨어나지만 선택은 그 중 하나만 되지요.

원래 그런것이다라고 생각하시면 될 것 같습니다.

prefork를 통해 다중 클라이언트를 처리하려면, listen socket과 accept되어 나온 socket이 동시에 select에 들어가게 됩니다.
이 경우 주의하실 것은, 동시에 두 작업을 하나의 프로세스에서 하기 때문에 자칫 클아이언트 쪽 소켓의 생성 소멸과 서버 소켓 accept 사이에서 프로세스의 상태 천이를 잘 설계하셔야합니다.

http://pynoos.x-y.net/cgi-bin/wiki/wiki.pl?Server_Frames

졸필이긴 합니다만 도움이 되시길 바랍니다.

김충길의 이미지

질문하신분의 문제는 우연히 한 서브 프로세서에서만 계속 accept가 된다는거
같은 맞지요? (좀더 psedo 코드 형태로 사용하시는 방법을 설명이 있다면
자세한 답변이 이루어 질 수 있을거 같습니다.)

pre-fork + select의 문제는 select 하는 모든 프로세스들이 다 함께
깨어나서 그들 모두 accept를 호출하다가 오직 하나만 성공합니다.
이 방식의 문제가 cpu 타임을 효율적으로 쓰지 못한다는 단점 입니다.
accept가 한개만 될거라면 구지 프로세스가 다 select로 부터 깨어나고
accept를 호출할 필요가 있나 하는건데 이 문제는 apache 의 효율성과 관련에서
이슈화 된적이 있고 apache는 select 하는 프로세스들간 serialize를 적용하는
걸로 한걸로 알고 있습니다.

관련해서 아래 링크를 참조 하세요.

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

링크 페이지에서 아파치 성능 관련 링크를 또 보십시요.
특히 아래 부분 같은 설명은 좀더 쉽게 다가 올듯 하네요.

Quote:

for ( ; ; ) {
accept_mutex_on ();
for ( ; ; ) {
fd_set accept_fds;

FD_ZERO (&accept_fds);
for (i = first_socket; i <= last_socket; ++i) {
FD_SET (i, &accept_fds);
}
rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
if (rc < 1) continue;
new_connection = -1;
for (i = first_socket; i <= last_socket; ++i) {
if (FD_ISSET (i, &accept_fds)) {
new_connection = accept (i, NULL, NULL);
if (new_connection != -1) break;
}
}
if (new_connection != -1) break;
}
accept_mutex_off ();
process the new_connection;
}


(quote에서는 indent가 무시 되는군요.)
for ( ; ; ) {
    accept_mutex_on ();
    for ( ;  ; ) {
        fd_set accept_fds;

        FD_ZERO (&accept_fds);
        for (i = first_socket; i <= last_socket; ++i) {
        FD_SET (i, &accept_fds);
        }
        rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
        if (rc < 1) continue;
        new_connection = -1;
        for (i = first_socket; i <= last_socket; ++i) {
        if (FD_ISSET (i, &accept_fds)) {
            new_connection = accept (i, NULL, NULL);
            if (new_connection != -1) break;
        }
        }
        if (new_connection != -1) break;
    }
    accept_mutex_off ();
    process the new_connection;
    }

ps.
질문하신 문제의 답은 아니지만 관련 사항이라 올립니다.

screen + vim + ctags 좋아요~

댓글 달기

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