fork() 시에 defunct

dotri의 이미지

fork() 로 프로세스를 생성하는 프로그램이 있는데요.. 이게 프로세스를 좀 많이 반복적으로 생성하거든요. 그런데 생성된 프로세스를 보니까..

14067 pts/1    R      0:00 ./Update-Server
14068 pts/1    Z      0:00 [Update-Server <defunct>]

이렇게 나옵니다. 그리고 프로그램이 좀 돌다보면 어느샌가 새로운 프로세스를 생성하지 못하는 상태가 되구요. <defunct> 가 무척 신경쓰이는데.. 어떨때 나타나는 현상인가요?

서지훈의 이미지

이건 child process가 죽었는데 parent process가 자원을 제대로 수거하지 않은 상태입니다.
이러한 상태는 죽은 상태로 child process가 memory와 process entry를 그대로 유지가 되기 때문에 계속적으로 프로그램이 될게 되면 언젠가는 자원이 모자라 시스템이 멈추게 됩니다.
이러한 경우의 처리는 SIGCHLD signal을 잡아서 자식이 무사히 종료 되기를 parent가 기다려줘야 합니다.
이에 대한 좀 더 자세한 내용은 이 게시판에서 SIGCHLD로 검색을 해보셔도 어느정도 나올거 같군요.

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

익명 사용자의 이미지

<defunct> 를 통상 좀비 프로세스라 칭합니다.

발생원인
자식 프로세스가 종료할 경우 부모 프로세스에게 시그날을 송부합니다.
이때 부모프로세스가 정상적으로 시그널을 접수하면 자식은 죽지않고
계속해서 시그널을 접수받기를 기다리는 상태가 되며,
이때를 좀비프로세스 상태로 부릅니다.(살아있는죽은시체 프로세스)
해결방안
부모 프로세스가 시그널을 접수처리함.
1) 부모프로세스가 종료했을 경우 자식프로세스의 부모는 1번 프로세스가
승계하여 정상적으로 시그널 접수처리함.
2) 부모프로세스가 기동중이었을 경우 프로그램내부에서 sigcatch하여
시그널 접수 처리하는 로직 필요함. (waitpid함수등 사용)
좀비프로세스 문제점
1) 자원를 점유하고 있음.
2) 좀비프로세스가 늘어나게 되면 시스템 자원사용(프로세스 생성 등)이
불가능하게 될 수 있거나 성능이 떨어짐.
3) 좀비프로세스는 kill로도 죽일 수 없음. 시스템 리부팅해야 함.

dotri의 이미지

이 코드를 봐 주시겠어요?

void ChildProcess( void ); // 어떤 작업을 하는 간단한 함수

int main( void )
{
    pid_t PID;
    int status;

    while( 어떤 이벤트 발생시 )
    {
        PID = fork(); // 프로세스 생성하고
        if( PID == 0 ) 
            waitpid( -1, &status, 0 ); // 부모는 자식이 끝날때까지 대기
        else {
            ChildProcess(); // 자식은 자신이 할 일을 한 후
            exit( 0 ); // 종료
        }
    }

    return 0;
}

이 코드에서 위와 같은 좀비 프로세스가 계속 나오는데요.. 부모에서는 자식을 생성하는 즉시 waitpid() 해줘서 끝나기를 기다려주므로 좀비프로세스가 생기지 말아야 할것 같은데 왜 자꾸 좀비 자식이 생기는지 모르겠어요.

그리고 또 하나는.. 이 프로그램이 최초 실행되어서 첫번째 자식 프로세스가 생성된후, 코드상에서 exit() 함수를 통과하면서 프로그램을 실행한 쉘이 꺼져서 로그아웃되거든요. 다시 로그인해보면 프로그램은 살아서 돌아가는 상태구요. 좀비 프로세스를 계속 만들어내면서..

어떤 처리를 잘못한건지 모르겠습니다.

eminency의 이미지

dotri wrote:
이 코드를 봐 주시겠어요?

void ChildProcess( void ); // 어떤 작업을 하는 간단한 함수

int main( void )
{
    pid_t PID;
    int status;

    while( 어떤 이벤트 발생시 )
    {
        PID = fork(); // 프로세스 생성하고
        if( PID == 0 ) 
            waitpid( -1, &status, 0 ); // 부모는 자식이 끝날때까지 대기
        else {
            ChildProcess(); // 자식은 자신이 할 일을 한 후
            exit( 0 ); // 종료
        }
    }

    return 0;
}

이 코드에서 위와 같은 좀비 프로세스가 계속 나오는데요.. 부모에서는 자식을 생성하는 즉시 waitpid() 해줘서 끝나기를 기다려주므로 좀비프로세스가 생기지 말아야 할것 같은데 왜 자꾸 좀비 자식이 생기는지 모르겠어요.

그리고 또 하나는.. 이 프로그램이 최초 실행되어서 첫번째 자식 프로세스가 생성된후, 코드상에서 exit() 함수를 통과하면서 프로그램을 실행한 쉘이 꺼져서 로그아웃되거든요. 다시 로그인해보면 프로그램은 살아서 돌아가는 상태구요. 좀비 프로세스를 계속 만들어내면서..

어떤 처리를 잘못한건지 모르겠습니다.

PID가 0을 리턴하면 부모가 아니라 자식 프로세스 아닌가요? pid를 부모에게 알려주지 않으면 부모가 알 방법이 없으니까요...ㅡ.ㅡ

부모는 자식 할 일 대신 해주고 죽어버리고, 자식은 계속 기다리고 있어서 문제가 생기는 듯...

노루가 사냥꾼의 손에서 벗어나는 것 같이, 새가 그물치는 자의 손에서 벗어나는 것 같이 스스로 구원하라 -잠언 6:5

dotri의 이미지

정말 그렇네요. 아우 이런 간단한걸 삽질하고 있네요.
답변주신분들 감사합니다.

댓글 달기

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