multi process - multi thread 서버 환경에서의 static 변수의 반환시점.

ssanighe의 이미지

안녕하세요.
서버 프로그램을 만들다가 궁굼한 점이 있어 글을 올려봅니다.
프로그래밍 언어는 c 이고,
서버 환경은 Solaris 입니다.

서버는 n개의 프로세스가 각각 m개의 thread를 만들어 동작하고 있습니다.

프로세스는 n개가 항상 유지가 되며,
임의의 프로세스 p1이 tcp소켓을 통해 입력값을 받으면,
p1은 thread t1을 생성하여 t1에게 job을 준 뒤,
while문을 돌아 다시 accept wait 상태로 돌아가게 됩니다.

주로 보시던 preforked multi threads 방식의 서버입니다.

문제는 이때 t1 내의 함수에서
static 변수 s1 이 생성이 되면
t1이 종료된다 하더라도 p1은 종료되지 않기 때문에 s1은 kernel에 반환이 되지 않게 될 거라는 겁니다.
static 변수는 해당 scope에 종속적이지 않으며, 프로세스의 종료시점에 반환되기 때문이죠.
따라서 job이 계속 들어오게 되면 static 변수는 계속 생성 되고 반환되지 않게되어 결국은 static 변수 역역이 full이 나게 되는 현상이 발생될까 우려됩니다.

테스트를 해보니 job이 들어오는 만큼 비례하여 process의 총 memory가 늘어나더군요.

컴파일시 -D_REENTRANT 옵션을 주게되면 각각의 쓰레드가 각각의 변수를 관리하기 때문에 쓰레드 종료시 static 변수도 반환할 꺼라는 후배놈의 추측이 있었지만, 테스트 결과를 보면 그렇지 않은 것 같습니다.

Heap 영역을 malloc 했다면, thread 종료시점에 free 해주면 되지만,
static 영역도 사용자가 강제로 free해 줄수 있는 건가요?

ssehoony의 이미지

아뇨 static은 쓰레드를 생성해도 증가하지 않습니다.
아마 메모리릭은 다른데서 발생한걸겁니다.

함수내에서 static 변수를 하나 선언했다면, 그 변수는 모든 쓰래드에서 공유합니다.
그래서 strtok 같은 함수는 static 변수를 사용해서 구현되기 때문에
멀티 쓰래드에서는 문제를 야기 시킵니다.
그래서 strtok_r 과 같은 멀티쓰래드용 함수가 별도록 제공되는 것이지요.

멀티쓰래드 프로그램에서는 함수내에 static 변수를 사용하면,
reentrance에 문제가 발생하기 때문에 static 변수를 사용할때는 고려해야 할게 많습니다.

static 변수는 그냥 해당 함수 내에서만 접근 가능한 글로벌 변수랑 동일하다라고 생각하시면 됩니다.
글로벌 변수는 모든 쓰래드에서 공유하듯 static 변수 역시 동일합니다.

static 변수에 대해 좀 더 자세히 이야기 하자면
static 변수의 메모리는 프로세스가 처음 시작할 때 특정 메모리주소로 할당이 되고
0 값으로 초기화가 됩니다.
프로그램 구동중에 새로 생성되거나 사라지지 않습니다.
그래서 dynamic과 반대인 static인 것이지요.

백문불여일견!!
한번 위에 말한 사실을 확인 할 수 있는 코드를 생성해서 테스트 해보세요
즉 스레드 1 에서 static 변수에 특정 값을 셋팅하고 스레드 2에서 그 함수의 static 변수 값을 확인해 보세요
1에서 셋팅한 값이 2에서 튀어 나올겁니다.

mach의 이미지

다른 원인이 있는지도 모르지만, 간혹 질문에 회자되는 것으로 예측해 봅니다.

쓰레드의 join문제로 기인한게 아닌가? 예측해봅니다.
쓰레드 사망시(프로세스말고..) 쓰레드는 기본적으로 자원반납을 스스로 하지 않습니다.
(마치, 프로세스의 좀비?와 유사하다고 할까요? 시그널을 받아주지 않으면 지속되는...)
그래서 명시적으로 쓰레드사망시 자원반납을 하도록 해야하는데,...
방법은 3가지 정도 있습니다.
1) 부모가 취할 수 있는 방법(쓰레드를 생성해준...)
1-1) 죽음을 지켜보고, 받아들여주자!
-마더(쓰레드를 생성시키는 루프가 되는 ..)에서 pthread_join()을 적절히 불러준다.
1-2) 죽음을 보지 않겠다. 단지 만들어만 줄뿐....
- pthread_create()시에 파라메터를 적절히 세팅해서 (thread attribute), 쓰레드가 사망시 해야할 행동을 미리 정해준다.(자원 반납한다는...)
2) 스스로 죽자!
- 각 쓰레드가 시작될때, 시작부분(주로 쓰레드의 시작함수가 되겠지요)에서 pthread_detach()를 불러준다.

위 3가지 중 하나를 채택하는 것을 의미합니다. 멀티쓰레드 코딩시 선택아닌, 필수사항이겠지요.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

댓글 달기

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