fork()와 exec()를 이용한 새로운 프로그램 실행하기

tkfkdgody의 이미지

안녕하세요.
현재 4개의 스레드가 돌면서 각기 다른 일을 하는 프로그램을 만들고 있습니다.
그 4개의 스레드 중 하나의 스레드에서 다른 프로그램(A)이 실행중인지 감시하는 역할을 하는데요..
이 감시 스레드에서 A프로그램을 실행하고 감시하다가 죽었다 판단되면 A프로그램의 pid를 가지고 kill시킨 다음
재 실행 시킬려고 하는데 얕은 지식이라 의문점이 많이 드네요.
의문점은,
1. 하나의 스레드 내에서 fork()를 호출했는데 책을 보니 fork()하면 프로세스랑 같은 자식 프로세스를 하나 만든다고
되어 있는데 이렇게 되면 제가 안쓰는 나머지 3개의 스레드 리소스까지 잡아 먹지 않을까하는 생각이 드네요.
아래의 소스는 제가 구현할려고 생각한 구조입니다.

int AAA::ThreadRun()
{
  pid = ForkProcess();
  execl("/home/wk/workspace/TestA", "./A", NULL); //처음에 감시 프로그램 실행
  while (1)
  {
    ....
    .... //감시하고자 하는 프로그램이 죽었는지 살았는지 판단하는 루틴
     if ( 감시 프로그램이 죽었다면 )
    {
       kill(pid, SIGTERM);
       // 자식 프로세스가 죽으면 자원 해제 waitpid 
       pid = ForkProcess();
       exec("/home/wk/workspace/TestA", "./A", NULL); // 새로 A프로그램 실행
    }
  }
}
 
int ForkProcess()
{
  int pid = fork();
  return getpid();
}

2. exec("/home/wk/workspace/TestA", "./A", NULL);
위 함수를 저런식으로 썼는데 A라는 프로그램이 실행이 되질 않네요;; 함수찾아서 쓴다고 썼는데.. 흠..;;

3. 책에는 fork/exec 함수가 유닉스/리눅스에서 프로세스를 생성하고 실행하기 위한 유일한 방법이라고 나와있는데
새 프로세스를 실행하고 죽일 수 있는 다른 방법이 혹시.. ; 있을런지요?
제가 하고자 하는건 감시프로그램을 실행하고 죽이는 역할을 추가할려고 합니다.

흠.. 읽어주셔서 감사합니다.
조언이 될만한 댓글 부탁드리겠습니다.

cinsk의 이미지

1. multi-threaded 프로세스가 fork()를 실행하면, fork()를 실행한 thread만 살아 남습니다. 나머지 thread는 없어집니다. (이때, 해당 thread-specific handler 등은 호출되지 않으므로 주의해야 합니다. 없어지는 thread에서 건 lock은 해제되지 않습니다.)

2. exec(3)은 exec로 시작하는 함수들의 대표 이름?입니다. 실제 존재하는 함수 이름이 아닙니다. 인자 구조를 보니, execl(3)를 쓰는 게 좋을 것 같군요.

3. fork(2) 대신 vfork(3)를 쓸 수도 있습니다만, 질문한 의도와는 별 상관이 없을 듯 하군요.

마지막으로 소스를 대충 보면, wait()를 하는 부분이 없네요. TestA가 daemon 형태로 re-parent한다면 상관없겠지만, 그렇지 않다면 아마 zombie 프로세스가 될 듯 합니다. zombie를 막으려면 daemon 형태로 만들거나, wait()로 child process의 return을 받아야 합니다. 그리고 이 때, SIGCHLD를 비롯, signal 처리를 하려면 pthread_sigmask() 등을 써서, signal을 원하지 않은 thread에서는 해당 시그널이 발생하지 않도록 block시켜야 합니다.

--
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://www.cinsk.org/cfaqs/

tkfkdgody의 이미지

한가지 더 이상한 점은,

       pid = ForkProcess();
       execl("/home/wk/workspace/TestA/A", "A", NULL); // 새로 A프로그램 실행

했는데 A라는 프로그램이 두번 실행되면서 죽어버리네요. 왜 두번 실행이 되는지 모르겠네요;;

세심한 답변 감사드립니다.

책을 봤을때 얻어진 것보다 많은 도움이 되었습니다. 다시 한번 감사드립니다.
말씀대로 한번 다시 구현해봐야겠습니다.

활기찬 한주 되십시요~

cinsk의 이미지

fork()한 후에 return 값을 테스트해서 parent인지 child인지 검사하지 않고 바로 execl()을 부르니, parent와 child에서 모두 execl()이 실행되서 그런 것입니다.

마지막으로 execl 계열에서 마지막 인자로 NULL을 줄 때, (char *)NULL로 하는 편이 좋습니다.

--
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://www.cinsk.org/cfaqs/

tkfkdgody의 이미지

넵.. 해봤는데 시작하고 몇줄 프린트하더니 좀비가 되어 버리네요.

 
int ForkProcess()
{
  int pid = fork();
  if (pid > 0)
  {
 
  }
  else 
  {
    exec("/home/wk/workspace/TestA", "./A", NULL); // 새로 A프로그램 실행
  }
  return pid;
}

실행을 했는데 A 프로그램이 실행되면서 앞에 몇줄만 실행하고 좀비가 되어 버리네요..

wk      5805  0.0  0.3  60768  3528 pts/0    Sl   13:22   0:00 /home/wk/workspace/TestA/A
wk      5812  0.0  0.0      0     0 pts/0    Z    13:22   0:00 [A] <defunct>

흠.. 너무 귀찮게 하네요;; 답변 감사합니다~

tkfkdgody의 이미지

혹시 A라는 프로그램이 실행되면 몇개의 thread가 도는데 그것때문에 그럴수도 있는지요...

댓글 달기

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