여러개의 프로세스를 돌리는 프로그램 질문이요....

은영신랑의 이미지

:roll: 프로세스가 4개가 차례로 도는 프로그램을 만들고자 하는데요, 꼭 차례대로 돌아야하며 하나라도 죽으면 종료가 되어야 합니다.

우선 task를 돌려주는 프로그램이 있어서 fork()->execl()로 각각의 task를 실행하게 해주고, 공유메모리와 4개의 세마포어를 이용하여 서로 주고 받으면서 차례대로 실행을 하는것입니다. 각각의 태스크는 무한루프안에서 자기의 세마포어를 기다리다 받으면 실행하고 종료되면 다른 프로세스에서 세마포어를 주고 자기의 세마포어를 기다리는 식입니다.
그리고 아직은 구체적이지 않지만 모니터링 해주는 프로세스가 있어서 원하는 시간에 각각의 프로세스가 시작되고 종료되는지 검사를 해주어야 합니다.

위와 같은 방법으로 구현하는 중인데 더 좋은 방법이라던지 안좋은 점, 조언등에 대해서 이야기좀 해주셨으면 합니다.

은빛연어의 이미지

내용은 무슨 말씀인지 이해하기가 어렵네요.... ^^;;;
제목에 "프로세스가 4개가 차례로 도는 프로그램을 만들고자 하는데요, 꼭 차례대로 돌아야하며 하나라도 죽으면 종료가 되어야 합니다"만 봤을때는 만들기가 쉽네요...

fork해서 생성된 프로세스는 죽을때 parent 프로세스한테 죽는다는 signal을 보내거든요.. 그래서 parent 프로세스는 죽었다는 signal을 받고 죽은 child 프로세스를 알아내서 다시 띄울수도 있꾸... 아니면 질문에서처럼 다 죽일수도 있구요... ^^*
답변이 되셨는지...

choissi의 이미지

exit할때 리턴하는 값을 정상이라면 0으로 하신다던지
규칙을 정한 다음 코딩을 하시면 되겠죠

아래의 코드는 정상종료이면 exit(0);
으로 종료한 것이고 나머지는 다 에러로 보고 16번 정도
다시 해보고 종료 처리 합니다.

        for(i = 0; i < Dinfo_ALL_CNT; i++){
                retry_cnt = 0;

                if (pDinfo_ALL[i].rid >= start_id && pDinfo_ALL[i].rid <= end_id ) {

retry:
                        /*
                        printf("%c : [%s] [0x%02x][%-16.16s] [%-32.32s]\n",
                                pDinfo_ALL[i].rid,
                                (pDinfo_ALL[i].master == 1) ? "마스터" : "시세  ",
                                pDinfo_ALL[i].id,
                                pDinfo_ALL[i].service,
                                pDinfo_ALL[i].name);
                        */

                        snprintf(exec_cmd, sizeof(exec_cmd),"%s %c %c",
                                filename,
                                pDinfo_ALL[i].rid,
                                cast_gb);

                        rtn = my_system (exec_cmd);
                        //sleep(5);

                        printf("결과 -> %s rtn[%d]retry[%d]\n\n",  exec_cmd, rtn, retry_cnt);

                        if(rtn != 0 && retry_cnt < 16) {
                                retry_cnt++;
                                sleep(8);
                                goto retry;
                        } else if (rtn != 0 && retry_cnt >= 16) {
                                exit(-1);
                        }
                        sleep(5);
                }
        }
}



/*******************************************************************************
 * 설명      : 커맨드 실행
 * Prototype : int my_system (const char *command)
 * Arguments :
 * Return    :
 ******************************************************************************/
int my_system (char *command) {
        int pid, status;

        if (command == 0)
                return 1;

        pid = fork();
        if (pid == -1)
                return -1;
        if (pid == 0) {
                char *argv[4];
                argv[0] = "sh";
                argv[1] = "-c";
                argv[2] = command;
                argv[3] = 0;
                execve("/bin/sh", argv, environ);
                exit(127);
        }

        do{
                if (waitpid(pid, &status, 0) == -1) {
                        if (errno != EINTR)
                                return -1;
                } else
                        return status;
        }while(1);
}

울랄라~ 호기심 천국~!!
http://www.ezdoum.com

은영신랑의 이미지

답변 너무너무 감사드립니다.
우선 제가 에매하게 질문을 한것 같네요.

실제 요지는 각각의 task가 죽었을때 처리방법 보다는 , 각각의 프로세스가 잘 도는지 검사를 하는 모니터링 방법입니다.
각각의 task가 다음과 같이 되어 있습니다.

 ...
           while(1){
                    semaphore wait;
          
                     처리...

                      semapore  give;
           }     

그러니깐 프로세스는 자기의 세마포어를 기다리다 들어오면 수행하고 또 세마포어를 준 후 또 기다리는 방식입니다. 또한 세마퍼어를 받고 일정시간동안 실행을 못하면 종료시켜야 하구요.
보통 순서를 매겨서 프로세스들이 돌고 , 모니터링을 한다면 어떤식으로
코딩을 하시는지 좀 배우고 싶습니다.
은빛연어의 이미지

세마포어는 특정한 부분을 내가 건드릴때 다른넘(?? ->프로세스 ^^)들이 건드리지 못하게 락을 거는 것이란것은 잘 아실테지요~~ ^^*

그런데 여러 프로세스를 구동시키면 늦게 시작한 넘이 빨리 돌아서 먼저 들어가려고 할때도 생기죠.. 순서대로 돌아가면 좋켔구만.. ^^*
그래서 이와같은 것을 피해가기 위해서 다음과 같이 할 수가 있습니다.
각 프로세스마다 특정한 값을 가지게 하는거죠.. 예를들면,
aaa1 프로세스는 proc_type => 1로
aaa2 프로세스는 proc_type => 2로
...
fork를 해서 여러개의 프로세스를 구동 하드라도 프로세스가 가지는 타입을 다르게 정할수가 있습니다.
그렇게 한뒤에 처리하고 싶은 부분에다가 if문을 넣는거죠... if문에 들어가는 변수는 님이 말씀하신 공유메모리에다가 만들어주시면 되구요~~ 타입이 1부터 쭈욱해서 10까지 있으면, if 문에 들어가는 변수에다가 +1을 하는겁니다.
물론 마지막에서는 1로 다시 만들어주고요... ^^ 변수에 들어 있는 값이 곧 자기가 수행할 차례를 의미하는 것이 됩니다.
이런식으루 하면 어떤 프로세스가 먼저 오드라도 자기가 처리할 순서가 아니면 그냥 빠져나갈테니까 순차적으로 만드는게 가능하져...

그리구 프로세스가 시간내에 수행하지 않았을 경우는 어떻게 아느냐...^^*
아는 수가 잇쪄... 아까 공유메모리에 만든 변수를 이용하는겁니다..
fork를 한 parent 프로세스가 변수의 값이 변하는것을 감지하고 있다가 timer를 돌리져.. 타임아웃이 날때까지 값이 변하지 않으면 해당 프로세스가 수행하지 않은 것으로 판단하면 되겠쪄... ^^

물론 다른방법으로 구현할수도 있구요... 방법은 여러가지가 있을수가 있으니깐요. 도움되시길~

sunyzero의 이미지

복잡하게 짜지 않고 4개의 프로그램을 짜고, 쉘스크립트로 돌리면서 안에서 리턴값을 검사해도 될것 같은데... 쉘스크립트를 사용하면 안된다고 합니까?

흠... 어차피 4개의 프로그램태스트를 execl 계열을 사용한다면 따로 있는 프로그램인듯 싶은데, 간단하게 쉘스크립트로 끝내보시죠?

========================================
* The truth will set you free.

댓글 달기

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