2012-04-01 25 views
0

の* nixでCを使用して非同期プロセスの起動しますプロセスは、親プロセスに戻って、親プロセスと親プロセスとの親プロセスになる)を生成し、<Some code>ブロック終了後、end()関数はkillとなり、start()に関連付けられたプロセスIDになります。 これを行う方法がわかりません。特に、親子コードブロックを非同期にする部分があります。助けが要る。ありがとう。は、私はこのような状況がある

編集:メンバーからの助けを得た後、私はこのコードを書くことができましたが、これは問題を抱えています。誰かがエラーを指摘できれば素晴らしいかもしれません。私が_do_()に欲しいのは、_stop_()がそれを殺すことができない場合、決して終了できない子プロセスを開始することだけです。しかし何らかの理由で親プロセスが失われており、ループがwhile()のループで無期限に実行されます。

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <string.h> 
#include <signal.h> 
#include <errno.h> 

pid_t id = 0; 

int _do_() 
{ 
//int status; 
pid_t childpid; /* variable to store the child's pid */ 
FILE *fp= NULL; 
childpid = fork(); 

//child stuff 
if (childpid == 0) 
{ 
    id = getpid(); 
    fp = fopen ("Log.txt", "w+"); 
    while (1) 
    { 
     fprintf(fp, "Logging info...\n"); 
     fflush(fp); 
    } 
    fclose(fp); 
} 

if (childpid < 0) /* fork returns -1 on failure */ 
{ 
    perror("fork"); /* display error message */ 
    exit(-1); 
} 

return 0; 

} 

//kill child process in _do_() 
int _stop_() 
{ 
    int en; 
    printf("Going to kill child ID: %d\n", id); 
    if (kill (id , SIGKILL) < 0) 
    { 
    en = errno; 
    printf("Error while trying to KILL process: %s\n", strerror(en)); 
    } 
    printf("Logging ended\n"); 

    return 0; 

} 

int main(int argc, char* argv[]) 
{ 
    int i; 

    _do_(); 
    for (i = 0; i < 200; i++) 
    ; 
    _stop_(); 
    printf("\nEnded...\n"); 
    return 0; 
} 

EDIT2:私は私が望んで行うことができませんでした、プロセスを殺すが、end()からstart()で開始代わりにデーモンプロセスを開始し、それはいくつかのあらかじめ指定された制限値に達したファイルサイズまでのファイル上の値をダンプしてみましょう。これは私が望むものに最も近いものです。

+0

どのオペレーティングシステムこのような何か? –

+0

[これは質問です](http://stackoverflow.com/q/7794273/960195) - 'start'を実装するコードが含まれており、' end'のコードを要求しています。 –

+0

Linuxシステム... – Sayan

答えて

4

fork/exec/killの動作に関するいくつかのサンプルが必要です。

通常、プロセスをフォークします。プロセスは、子プロセスと親プロセスの2つのプロセスを作成します。子プロセスは戻りコード0で 'fork'から戻ります。親プロセスは子プロセスのpidを返します。これはあなたが子プロセスか親プロセスかを知る方法です。

他のプログラムを実行したい場合は、子プロセスから「exec」を呼び出すことができます。しかし、次のようなコードもあります:

pid = fork(); 
if (pid == 0) 
{ 
    // do child stuff here 
    exit (0); 
} 
if (pid == -1) 
// failed to fork, deal with it 

// parent code goes here 
... 
... 
kill(pid, SIGKILL); // you can kill your child process here if you want to. 
        // thanks to Adam Rosenfield for pointing out the signal number has to be sent 

チュートリアルを見ると簡単です。 Windowsは別の方法で動作するので、コードをウィンドウに移植したい場合は、forkはexecとexecの両方を使用します。ウィンドウは実際にはプログラムの同一コピーを作成しないため、常に新しいプログラムを生成します。

私は、WindowsプログラマがUNIXプログラマ以上のスレッドを使用する傾向があると私は考えていません。Windows上で新しいプロセスを作成することは大きな問題です。 UNIX上ではそれほど大きな取引ではありませんが、スレッドよりも大規模です。しかし、スレッドプログラミングはそれほど難しく、比較すると、本当に本当に必要な場合を除き、おそらくそれから離れることになります。

編集: 「kill(pid、SIGKILL)」を実行する前に、あなたの子供がまだ生きていることを確認してください。あなたの子供が死亡した場合、pidは別のプロセスによって再利用された可能性があります。その場合、あなたはいくつかのランダムなプロセスを終了することができます。

edit2: コードにバグがあります。 「//ここ子なものを行う」セクションで

1 - remove 'int id...' 
2 - move pid_t childpid; from function into global scope 
3 - kill childpid, not 'id' 
+0

特に編集と素敵なサマリー – Sayan

+1

+1のためにありがとうございますが、ペタンティックであるため、 'kill(pid、SIG)'( 'kill(pid)'ではなく) 'SIG'はシグナルの名前ですこの場合、おそらく 'SIGKILL'を送ります。 –

+0

私は問題を抱えています。start()には、2つのセクションがあります.1つはchildのためのもので、もう1つはparentのためのものですが、私は親から出ていますが、childではありません。その後、 'end()'で、私は 'kill(pid、SIGKILL)'を発行しています。ここでpidはグローバル変数で、私はその子のpidを取得します。しかし、どういうわけか、子供はまだ生きている... – Sayan

1

、あなたは二回目をフォークし、元の子プロセスを殺す、孫を継続させることが、今initプログラム(プロセスID 1)によって継承されたかもしれません。

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <sys/types.h> 

void OutputPids(const char *tag) 
{ 
    printf("in %s process %d, parent is %d\n", tag, getpid(), getppid()); 
} 

int main(int ac, char **av) 
{ 
    pid_t pid_child = -1; 
    OutputPids("original"); 
    if(-1 == (pid_child = fork())) { 
     perror("fork (for child)"); 
    } else if(0 == pid_child) {  /* fleeting child process */ 
     pid_t pid_grandchild = -1; 
     if(-1 == (pid_grandchild = fork())) { 
      perror("fork (for granchchild)"); 
     } else if(0 == pid_grandchild) { /* in grandchild */ 
      int i; 
      setsid(); 
      setpgid(0, 0); 
      for(i = sysconf(_SC_OPEN_MAX) ; i > 3 ; --i) 
       close(i); // close any stray filedescriptors 
      OutputPids("grandchild(ready)"); 
      // run the rest of the command line as a asynch command 
      execvp(av[1], av + 1); 
      perror("execvp"); 
      exit(1); 
     } 
     OutputPids("child(suiciding)"); 
     _exit(0);   /* skip atexit processing, etc. */ 
    } else {     /* original process */ 
     OutputPids("original(waiting)"); 
     wait(pid_child);    /* wait for child to die (quick) */ 
    } 
    OutputPids("original(after fork)"); 
    // stuff for your main routine continues here... 
    sleep(2); 
    OutputPids("original(done)"); 
    return 0; 
} 

例を実行します:

$ ./doublefork echo GRANDCHILD OUTPUT 
in original process 13414, parent is 22338 
in original(waiting) process 13414, parent is 22338 
in child(suiciding) process 13415, parent is 13414 
in original(after fork) process 13414, parent is 22338 
in grandchild(ready) process 13416, parent is 1 
GRANDCHILD OUTPUT 
in original(done) process 13414, parent is 22338 
$ 
関連する問題