[질문] 프로세스 대체

낙엽의 이미지

어떤 프로세스가 있습니다. 이 프로세스는 특저어 프로세스가 죽었는지 살았는지 검사를 하는데요, 만약 특정 프로세스가 죽었다면 그 프로세스를 구동시킵니다.(execl)

여기서 질문은, execl 말고 완전하게 A process에서 특정 B process를 구동시킬수 있는 방법은 없을까요?

sozu의 이미지

fork() 하신다음에 execl() 하시면 되지 않나요? :oops:

-----------
청하가 제안하는 소프트웨어 엔지니어로써 재미있게 사는 법
http://sozu.tistory.com

낙엽의 이미지

sozu wrote:
fork() 하신다음에 execl() 하시면 되지 않나요? :oops:

저도 이미 시도해 보았습니다만.. A process가 감시 및 특정 프로세스를 재기동 시키는 프로세스라 하고 기동해야 할 프로세스(즉, 특정 프로세스)를 B process라 했을 때,

A process는 B process가 죽거나 혹은 떠 있지 않으면 B를 재기동 시키는것을 시도하는데, 문제는 B process가 어떤 상용 라이브러리를 사용하는데 그 라이브러리를 읽어들이지 못한다는데 있습니다. 환경설정 파일도 없으면 다시 설정해서 쓰는데도 말이죠..

이 문제에 있어서는 예전에도 inittab에 A process를 올리려고 질문을 한 바 있습니다만 답변해 주신 분들 말씀대로 이것저것 시도를 해 봐도 모두 실패했습니다.

ps> 덧붙여 질문 하나 더요..

A process에서 system()명령으로 특정 프로세스를 구동시키면
system()에 의해 구동되는 프로세스는 완전 별개의 프로세스 인가요?
프로세스를 확인해 보니 sh -c 로 구동되는 것을 볼수 있는데요.. 이것이 어떤 의미인가요?

sozu의 이미지

낙엽 wrote:

A process에서 system()명령으로 특정 프로세스를 구동시키면
system()에 의해 구동되는 프로세스는 완전 별개의 프로세스 인가요?
프로세스를 확인해 보니 sh -c 로 구동되는 것을 볼수 있는데요.. 이것이 어떤 의미인가요?

일단 제가 답변 드릴수 있는 부분은

system()은 fork, exec, waitpid로 구현되어있지 않나요.

즉, 별개의 프로세스가 맞다고 생각합니다.

-----------
청하가 제안하는 소프트웨어 엔지니어로써 재미있게 사는 법
http://sozu.tistory.com

mach의 이미지

낙엽 wrote:

...
여기서 질문은, execl 말고 완전하게 A process에서 특정 B process를 구동시킬수 있는 방법은 없을까요?

"execl말고 완전하게????"
완전하게가 어떤 의미입니까?

* 참고
1) 유닉스(리눅스)에서 프로세스를 만드는 유일한 시스템호출(system call)은
fork()하나 뿐이다.
2) 한 프로세스가 다른 프로세스로 전이(완전히 바뀜)하는 것은 exec()시리즈이다.
1),2)에 의해 유닉스의 모든 프로세스는 생성된다. 즉, fork and exec이다.
표준 유닉스상의 어떤 유틸리티등도 이를 벗어나지 못한다.

Quote:
예) $ ls

1) 기본적으로 sh 프로세스가 존재
2) ls명령을 sh이 입력받음
3) sh은 fork()를 호출 (이로 인해 sh과 sh'이 존재하게됨)
4) pipe를 엮어서 ls가 출력한것을 sh이 받아서 표준출력에 출력하도록 만듬(pipe()시리즈)
5) sh'은 exec("ls")를 호출
6) sh'은 더이상 sh'코드가 아닌 ls코드로 전이(완전히 바뀜)
7) 'ls'는 자신의 기능을 수행
8 ) sh은 5-7이 벌어지는 동안 부모프로세스로써, 자식프로세스(sh'즉, ls)가 죽기를(SIG CHILD)를 대기함(wait() )
9) ls는 자신의 처리를 수행하고 종료
10) sh은 자식이(ls가) 죽음을 확인하고, 새로운 명령을 받을 준비가 되었음을
사용자에게 알리기위해 프롬프트 $를 출력함

이미 아시는 내용일텐데요, 구구절절이 써봅니다.

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

mach의 이미지

낙엽 wrote:

A process는 B process가 죽거나 혹은 떠 있지 않으면 B를 재기동 시키는것을 시도하는데, 문제는 B process가 어떤 상용 라이브러리를 사용하는데 그 라이브러리를 읽어들이지 못한다는데 있습니다. 환경설정 파일도 없으면 다시 설정해서 쓰는데도 말이죠..

음, 예측되는 문제로는 해당 상용라이브러리가 동시에 다수개 수행을 방해(?)하는지도
모르겠습니다. 복수개의 터미널에서 한번 B프로세스들을 돌려보시지요. 여러개 동시 수행가능한지?

낙엽 wrote:

이 문제에 있어서는 예전에도 inittab에 A process를 올리려고 질문을 한 바 있습니다만 답변해 주신 분들 말씀대로 이것저것 시도를 해 봐도 모두 실패했습니다.


inittab에 올려도 수행방식은 sh에서 ls수행하는 것과 동일합니다.
단지, 부모가 init라는 점을 제외하면 대동소이합니다. 즉, fork and exe시나리오를 벗어나지 못합니다.

낙엽 wrote:

A process에서 system()명령으로 특정 프로세스를 구동시키면

system()명령은 가급적 사용하시지 않는게 좋습니다. 아주 오래전에 사회 초년생일때, system()써서 만든 무지막지한 bbs서버 운영시에,
모뎀에 노이즈가 걸리니(묘한 해킹?), 외부 사용자에게 sh이 떨어지더군요 --;
저는 별로 권하고 싶지 않습니다. 아참, system()도 fork() and exec()메카니즘을 벗어나지 못합니다.

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

낙엽의 이미지

mach wrote:
음, 예측되는 문제로는 해당 상용라이브러리가 동시에 다수개 수행을 방해(?)하는지도
모르겠습니다. 복수개의 터미널에서 한번 B프로세스들을 돌려보시지요. 여러개 동시 수행가능한지?

예 가능합니다. 이미 확인했구요..

mach wrote:

inittab에 올려도 수행방식은 sh에서 ls수행하는 것과 동일합니다.
단지, 부모가 init라는 점을 제외하면 대동소이합니다. 즉, fork and exe시나리오를 벗어나지 못합니다. 중략..
아참, system()도 fork() and exec()메카니즘을 벗어나지 못합니다.

저도 그렇게 알고있습니다. 하지만 수행 결과는 딴판이라서요..
fork and exe 로 구동했을때는 수행되지 않던것이 system()으로는 수행이 되는 어처구니 없는 결과가 발생합니다.

우선은 sysetm()으로 수행하게 해 두었습니다만.. 걱정하시는 바 대로 저도 영 찝찝해서요..

낙엽의 이미지

아참. 덧붙여서,

fork() 해서 B process를 감시하다가 B process가 죽었을 때, A process에서 execl("B process")을 수행하게 되면 A process는 B process로 프로세스의 이미지가 복사되어 A process의 pid로 B process가 수행되는 것으로 알고 있습니다.

이렇게 되었을 때, 이 원래의 A process는 inittab에서 그 프로세스(원래 살리고자 하는 A process)가 죽었는지 알 수 있는 방법이 없는것인가요?

정리)
inittab --> A process 등록
A process --> B process 감시 및 재기동
B process 구동 시 A process pid로 구동
그렇다면 inittab에서는 A process가 죽었는지 살았는지 알수 있는 방법이??

김충길의 이미지

fork 후 execl 로는 수행이 안되는데 system으로는 수행이 된다하면
PATH, LD_LIBRARY_PATH와 관련된거 같습니다. PWD도 혹인해보시기
바랍니다.
ldd 명령어로 참조되는 so 파일들에 대해서도 살펴보세요.

낙엽 wrote:
mach wrote:
음, 예측되는 문제로는 해당 상용라이브러리가 동시에 다수개 수행을 방해(?)하는지도
모르겠습니다. 복수개의 터미널에서 한번 B프로세스들을 돌려보시지요. 여러개 동시 수행가능한지?

예 가능합니다. 이미 확인했구요..

mach wrote:

inittab에 올려도 수행방식은 sh에서 ls수행하는 것과 동일합니다.
단지, 부모가 init라는 점을 제외하면 대동소이합니다. 즉, fork and exe시나리오를 벗어나지 못합니다. 중략..
아참, system()도 fork() and exec()메카니즘을 벗어나지 못합니다.

저도 그렇게 알고있습니다. 하지만 수행 결과는 딴판이라서요..
fork and exe 로 구동했을때는 수행되지 않던것이 system()으로는 수행이 되는 어처구니 없는 결과가 발생합니다.

우선은 sysetm()으로 수행하게 해 두었습니다만.. 걱정하시는 바 대로 저도 영 찝찝해서요..

screen + vim + ctags 좋아요~

mach의 이미지

해결이 되었는지 궁금합니다.
음 .....
이전에 이글과 관련한 쓰레드가 있는것 같아서 읽어보았습니다.
대체로 문제가 없어 보이고, PATH관련 문제, shared object로딩문제
등등.. 다양한 검토를 하신것 같군요.

혹시, runlevel문제가 아닌지 모르겠습니다.(장님 코끼리...)
이전 쓰레드를 보니 SA:23:..... 이렇게 하신것 같은데, 현재 runlevel이 혹시 5(X windows환경)
아닌가요?
SA:235:....
쩝, 그냥 해본 소립니다.

그리고,

Quote:
그렇다면 inittab에서는 A process가 죽었는지 살았는지 알수 있는 방법이??

이것은 respawn 스크립트로 되어 있으니, init가 자기자식이니까, 죽으면 시그널받을테고, 자동으로 살려줄텐데요.
init죽는건 그야말로 끝장이니, 고려하실 필요도 없어보이고요.

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

dalekang의 이미지

여기에는 복잡한 관계가 있습니다.

단순히 system을 fork, execl, waitpid를 통해 구현할 수 있다고 생각하는 사람들이 많이 있습니다. 맞는 말씀입니다. 그러나 그렇게 단순하게 생각하면
실수하는 것이 있습니다. execl 이 프로그램을 실해하는 것이 아니라

system() 이런 방법을 사용합니다.

 execl("/bin/ksh -c 명령어", ....) 이렇게 실행한다는 것입니다.

execl에는 쉘 메타정보를 사용할 수 없습니다.
만약 사용하실려면 system을 사용하는 것이 당연하죠 ..
불안해 하실 필요없습니다. 다른 부분들이 정상이라면

그리고 앞으로는 코드를 올려 주셔야 정확한 답변이 가능합니다.

mach의 이미지

dalekang wrote:
execl에는 쉘 메타정보를 사용할 수 없습니다.

쉘 메타정보가 무엇인가요? 용어의 차이인지?????

만약, 환경변수라면 (environment variable) getenv, setenv등으로 처리할 수 있다고 생각합니다만.

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

dalekang의 이미지

물론 프로그램에서는 가능 합니다만 ....
그러나 execl 에서는 사용이 불가능하다는 말입니다.

execl("$HOME/..", ...);
execl(" ... > ...", ...);

등등과 같은 것들입니다.

더욱이 중요한 것은 제기억으로는 쉘 프로그램은 실행이 안된다는 것입니다.
이것을 말씀드리고자 했습니다. 대부분의 상용 프로그램은 시작 프로그램이들이 쉘로 랩핑 되어 있는것 같습니다...

최종호의 이미지

dalekang wrote:
...
더욱이 중요한 것은 제기억으로는 쉘 프로그램은 실행이 안된다는 것입니다.
이것을 말씀드리고자 했습니다. 대부분의 상용 프로그램은 시작 프로그램이들이 쉘로 랩핑 되어 있는것 같습니다...

쉘프로그램도 필요한 퍼미션만 있으면 수행이 됩니다. ^^
단 조건이 있지요.

% cat hello.csh
echo hello

% cat hello2.csh
#!/bin/csh
echo hello

hello.csh 을 exec 시키면 실행포멧 오류를 낼 것이고,
hello2.csh 을 exec 시키면 정상수행 될 것입니다.

#! 은 쉘이 해석하는 것이 아니라 로더가 해석하는 부분이며,
실행포멧을 나타내는 매직넘버 중의 하나입니다.

최종호의 이미지

system() 은 되는데 fork() / exec() 는 안된다는 건 뭔가 이상한 듯 한데요.
특히 system()이나 fork() / exec()를 수행시킨 녀석(감시프로세스)이
inittab 이나 cron 에 걸려있는 녀석이 아니라 사용자가
일반 명령행에서 수행시킨 것이라면 system()으로 수행시킬 경우와
환경변수 설정도 동일할테니 더더욱 이상하고요.

제 생각에는 일반적으로 환경변수 설정문제이거나
프로그램 내부적으로 다중수행을 막은 것으로 보이는데,
검증할 만한 자료가 없으니 더 자세히 말하기 힘들 것 같고요.

대부분 시스템에 시스템콜 트레이스 기능이 있으니,
감시 프로세스의 시스템콜을 추적해 보시면
(child 프로세스까지 따라가면서 추적하도록 옵션 주시고요)
오류가 발생하는 직접적인 원인을 아실 수 있을 것으로 생각됩니다.

그나저나 어떤게 안되는거고, 그때 errno 나 메시지, 시그널은 뭔가요? ㅡ.ㅡ?

최종호의 이미지

dalekang wrote:

...

system() 이런 방법을 사용합니다.

 execl("/bin/ksh -c 명령어", ....) 이렇게 실행한다는 것입니다.

execl에는 쉘 메타정보를 사용할 수 없습니다.
만약 사용하실려면 system을 사용하는 것이 당연하죠 ..
...

아마 fork/exec 로 구현했을 때 말씀하신 쉘 메타정보
(또는 쉘에서 제공하는 구문) 는 사용하지 않으셨을 것으로 보입니다.

system("prog");

execl("prog", "prog", (char *)0);
정도로 사용을 해서 쉘구문을 사용하지 않지 않았을까요? @.@

dalekang의 이미지

저는 프로그램 하다 일반적으로 하는 실수를 언급하기 위해
한 것이지 결코 깊은 부분을 이야기한 것이 아닙니다.

제가 정확한 정보를 드리지 못한 점 죄송합니다.

암튼 제가 언급했던 것은 같은 경우에
제가 경험했던 사람들의 실수를 언급한 것입니다.

^^;

댓글 달기

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