pre-fork 에서 select..

leilei의 이미지

pre-fork 기반 서버를 개발 중입니다.. linux이고.. 커널을 2.4구요..

prefork 후.. 모든 child 프로세스들이 select 후에 accept를 하는데요..
별다른 lock없이 잘 동작을 하는군요..

제가 알기론 멀티 프로세스가 같은 소켓을 accept를 하면 모두 select가
통과되고 한 프로세스만 accept을 하고 나머진 accept에서 블럭킹
되는걸로 알고 있었는데요..

테스트 해본 봐로는 한 프로세스만 select를 통과합니다.. -_-a

이게 정상인가요??
혹시 unix 쪽으로 옮기면 먼가 다른 동작을 보이는지도 궁금하네요..

김충길의 이미지

먼저 가져 간 프로세스가 select가 호출되고 accept를 호출하게 됩니다.

screen + vim + ctags 좋아요~

pynoos의 이미지

leilei wrote:
제가 알기론 멀티 프로세스가 같은 소켓을 accept를 하면 모두 select가
통과되고 한 프로세스만 accept을 하고 나머진 accept에서 블럭킹
되는걸로 알고 있었는데요..

테스트 해본 봐로는 한 프로세스만 select를 통과합니다.. -_-a

이게 정상인가요??
혹시 unix 쪽으로 옮기면 먼가 다른 동작을 보이는지도 궁금하네요..

select에서 accept 까지 갈동안 스케쥴이 다른 프로세스로 옮겨지지 않아서 그렇습니다. 재현가능하게 하려면, 2 CPU 이상에서 돌리던가, 아니면, 서버의 nice 값을 20정도로 준다음 과도한 접속을 시도해보세요.

leilei의 이미지

답변 감사합니다.. ^^;

테스트를 해 보니 말씀하신 것처럼 accept에서 블럭이 되어 버리네요.

그럼.. 멀티 프로세스에서 각 프로세스당 select는 어떻게 구현해야 하나요?
select 앞에 locking을 해야 할 것 같은데..
그럼 lock을 하지 않고 있는 다른 프로세스들은 select를 못하고 있게 되는게
아닌가요???

accept과 select 사이에 locking을 하면 이것 역시 안될듯 싶구요..

stoneshim의 이미지

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

leilei의 이미지

stoneshim wrote:
이거 한본 보세요.
http://bbs.kldp.org/viewtopic.php?t=24251

네.. 글 올리기 전에 찾아 보았던 글이네요.. :)

제 경우는 pre-fork 후 각 프로세스들이 select로 여러 connection을 유지하는 모델을 구현하고 싶은 경우입니다. 단순히 각 프로세스가 accept후 처리를 하고 다시 accept로 돌아가는 케이스는 아닙니다.

select 이전에 locking을 해서 성공한 프로세스만 fdset에 listenfd를 넣어 주는 방법도 생각해 봤는데... 이것 역시 효율적이라고는 생각되질 않는군요..

각 프로세스에 쓰레드폴을 구성해야 하나 고민 중입니다... :?
select 정도면 훌륭한데 말이죠

stoneshim의 이미지

TCP 연결을 유지해야 하는 상황이군요.

이런 상황이라면, 일단 생각 나는 것이...

단일 프로세스, TCP receive/send 전용 스레드 몇개, worker 스레드 몇개. 정도로 구성하시고, 내부적으로 session list를 관리합니다.

session list에는 state machine 을 사용하여, 해당 세션에서 input이 모두 입력되었는지를 확인하고, 다 입력되지 않고, block 이 된다면 현재의 상태를 session list에 저장하고, 다음 세션의 input을 처리하는 방법으로 처리될 것입니다.

물론 non-blocking i/o 를 사용합니다.

데이터는 tcp 스레드에서 모두 읽힌후 worker에게 전달되고, worker에서 작업이 완료되면 tcp 스레드에게 다시 전달되어 클라이언트에게 전달됩니다.

tcp 스레드를 복수개로 한다면, locking 정책을 잘 잡아야 하겠습니다.
select, poll 할 fdset을 tcp 스레드 별로 별도로 가져가고, listening fd만 공유해서 사용하는 것도 한번 생각해 볼만 할것 같습니다.

이 모델에서는 기능별로 스레드의 종류를 다르게 가져갔는데, 종류별로 다르게 가져가지 않고, 동일한 내용의 스레드 여러개로 서비스 할 수 도 있습니다.
session 처리하는 부분에 크리티컬 섹션을 두고 하나의 스레드만 진입할 수 있도록 한 후, 하나의 스레드가 tcp input을 읽어 프로토콜이 complete 되면 크리티컬 섹션을 빠져나와 작업을 하고, 곧바로 클라이언트에게 결과를 전송하도록 할수도 있겠습니다.

이런 모델 말고 말씀하신것과 같이 여러 프로세스가 각각 fdset을 별도로 가지고 있고, 각 프로세스에 스레드 풀을 달 수도 있겠습니다.

생각에 따라서 모델이 여러개가 존재할 수 있으니... 잘 생각하셔서 좋은 모델을 사용하시기 바랍니다.

이러한 처리에서 고려해 볼만한 내용이... pynoos 님 홈페이지에 pynoos 님께서 작성하신 문서가 있습니다. 한번 방문해서 참고해 보시길...
http://pynoos.x-y.net

구현방식이 확정되면 한번 알려 주시면 좋겠네요.

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

댓글 달기

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