prefork 와 select() 같이 쓰려면...

nomadism의 이미지

다음과 같은 구조로 서버프로그램을 짜려고 합니다..
이런 식으로 개발할때 어떤 문제가 발생할지에 대해 조언을 구합니다..

pid_t pid[임의의 수];
listen(serverfd)

for (i = 0; i < 임의의 수; i++) {
pid[i] = fork();
if (pid[i] == 0) {
child_proc(serverfd);
exit(0);
}
}

parent_proc(serverfd);
...
}

child_proc(serverfd) {
...
while (1) {
nready = select();

if (FD_ISSET(listenfd, &rset)) {
newfd = accept();
}

for (i = 0; i < 1024; i ++ ) {
if (FD_ISSET(sockfd, &rset)) {
client_sock(sockfd, &allset, maxi, client); }
}
}

...
}

parent_proc(serverfd) {
child_proc()와 비슷
}

즉 요지는 prefork의 빠른 응답과 select()의 한 프로세서가 fork() 나 새로운 쓰레드를 생성하지 않고 다수의 소켓을 다룰 수 있는 잇점을 둘 다 사용하려고 하는데 어떤 문제가 발생할 수 있는지 좀 알려주십시오...

ssehoony의 이미지

문제가 있지요
thundering herd problem 인가 하는 문제가 있습니다.
이게 뭔고 하니
님께서 말씀하시는 상황이라면
리슨 -> select -> accept 이런식으로 가자나요?
프리포크를 하면 select 상태인 녀석들이 여러녀석들인텐데
리슨소켓으로 하나가 반응이 들어오면 select 중인 모든 프로세스가
깨어납니다. 그리고 그중에 가장 먼저 accept 를 한 녀석이 사용자 처리를 하고
다른 녀석들은 accpet 에서 에러를 반환하져
접속이 빈번하게 발생하는 상황하에서 접속 요청시
매번 모든 프로세스가 깨어나는건 참~ 안 바람직한 현상이지요.

저라면
안정성을 위해 몇개 포크하고 그 다음 포퍼먼스를 위해 각 포크된
프로세스는 쓰레드풀을 이용해서 작동하는 포크 + 쓰레드 조합이 꽤 좋은
방법이 아닌가 하는 생각이 듭니다.
대표적인 예로 아파치 2.0 의 프로세스 관리 방식중 worker 방식이
위의 방식을 이용합니다.

pynoos의 이미지

devilhero wrote:
다른 녀석들은 accpet 에서 에러를 반환하져
접속이 빈번하게 발생하는 상황하에서 접속 요청시
매번 모든 프로세스가 깨어나는건 참~ 안 바람직한 현상이지요.

첨언하자면, 다른 녀석들은 non-block server socket을 accept 시도하지 않는한 에러를 반환하지 않습니다. 단지 accept에서 머물러 있습니다. 저도 매번 모든 프로세스가 깨어나는 건 참 안 바람직한 현상이라 지적하고 싶습니다.

listen하는 port가 하나라면, select를 쓰지 말고, 모든 pre-forked process가 accept에서 머물러 있어도 상관없습니다. 그중 한놈만 깨어나니까요.

하지만 여러 port를 listen한다면, select - accept 는 모든 녀석이 깨어나고 하나를 제외한 나머지들이 그 중 한 port에 멈춰버리는 현상이 발생합니다. 그러면, 다른 port로 접속이 들어와도 서비스가 불가능하지요.

여러 port를 listen한다면, semaphore 등으로 select에 들어가는 프로세스를 제한하여 하나만 들어가도록하면 됩니다.

nomadism의 이미지

답글 달아 주신 분들 감사합니다..
한가지만 더 물어보지여..

예를 들어 100개의 prefork한 자식들이 각각 accept를 하고,
그 상태에서 어떤 클라이언트의 연결이 시도되면, 모든 프로세서가 깨어나서 accept를 하려고 시도한다는 것이 문제라면, 그럼 pynoos 님의 말처럼 세마포어같은 차단기를 두어 한 프로세서만 accept를 하게 한다면 아무 문제도 없나요...

pynoos의 이미지

네..

정확히는 한 프로세스(프로세서는 CPU를 말하죠?)만 select에 들어가는 것입니다.

ssehoony의 이미지

문제가 동시에 여러 프로세스가 accept 를 시도한다가 아니고
하나의 accept 때문에 모든 프로세스가 깨어난다는게 문제이므로
세마포어를 사용해도 모든 프로세스가 깨어나게 되니깐 역시 그것도 문제일 것 같네요.

pynoos의 이미지

devilhero wrote:
문제가 동시에 여러 프로세스가 accept 를 시도한다가 아니고
하나의 accept 때문에 모든 프로세스가 깨어난다는게 문제이므로
세마포어를 사용해도 모든 프로세스가 깨어나게 되니깐 역시 그것도 문제일 것 같네요.

세마포어를 사용하여 select에 들어가는 프로세스를 하나로 제한하였으므로, 모든 프로세스가 깨어나지는 않습니다. 즉 다른 녀석들은 select에 들어가지도 않습니다.

댓글 달기

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