C言語関係掲示板

過去ログ

No.1129 子プロセスの終了と共にコマンド入力待ちの親を終了させる方法

[戻る] [ホームページ]
No.2155

子プロセスの終了と共にコマンド入力待ちの親を終了させる方法
投稿者---理音(2004/06/24 16:55:08)


いつも勉強させて頂いております。初投稿よろしくお願いします。

子プロセスの終了と共にコマンド入力待ちの親プロセスを
終了させる方法についてです。

環境は、Redhat 8 で、gccを利用しています。

サンプルソースは僕のやりたい事を理解していただく為に
簡略化して具体的なところはコメントにしました。
ご容赦下さい。

今のところ下記の様に子プロセスでグルグル処理をして
親プロセスから子へメッセージキューを使って停止など
のコマンドをおくって制御しています。

さて、この状態だと子へ特に指示をしないとfgetcで止まった
ままほったらかされる事になります。
子の処理が終わった段階で上手くfgetcで止まっている親も一緒に
終了させる方法は無いものかと考えています。

流石に子の方からkillシグナルを送るのは終了処理も
へったくれも無ないのでNGと考えてます。
あと、シグナルハンドラを作って終了処理をそこでするというのも
考えたのですが、何となく全体が見にくくなるのでイヤだなと
思っています。

ヒントで良いのでご助言を頂ければと思います。
根本的にこっちのやり方の方が良いなどあれば、そちらも
聞きたいです。

すごく初歩的なことを聞いてる気がして恐いですが
よろしくお願い致します。



//ヘッダ略・・・

int main(void){
    pid_t result_pid;
    int c;
    int i;

    result_pid = fork();

    switch(result_pid){
    case 0:
        //子プロセス
        for(i=0;i<1000000;i++){
            //ココでいろいろ処理をする
            //毎ループメッセージが来てないか確認して
            //あればそれにあった処理をする
        }
        exit();
        break;
    case -1:
        break;
    default:
        //親プロセス
        do{
            //コマンドを子プロセスに送る
            //停止・一時停止などなど
            //fgetcで'e'を入力すると停止コマンドを
            //送信しつつループ終了
        }while((c = fgetc(stdin)) != 'e');
        wait(NULL);
        break;
    }

    return 0;
}






No.2157

Re:子プロセスの終了と共にコマンド入力待ちの親を終了させる方法
投稿者---かずま(2004/06/24 20:06:33)


> あと、シグナルハンドラを作って終了処理をそこでするというのも
> 考えたのですが、何となく全体が見にくくなるのでイヤだなと
> 思っています。

シグナルハンドラは用意しますが、そこでは何もしないプログラムを書いて
みました。

NetBSD と Windows の Cygwin では動きましたが、Linux では試していません。
Linux での結果をお知らせください。
#include <stdio.h>
#include <signal.h>

void handler(int n) { }

int main(void)
{
    pid_t result_pid;
    int c, i;
    struct sigaction sa = { handler };
    sigaction(SIGCHLD, &sa, NULL);
    result_pid = fork();
    switch (result_pid) {
    case 0:
        // child
        exit(0);
    case -1:
        break;
    default:
        do {
            // parent
        } while ((c = fgetc(stdin)) != 'e' && c != EOF);
        wait(NULL);
        break;
    }
    return 0;
}



No.2158

Re:子プロセスの終了と共にコマンド入力待ちの親を終了させる方法
投稿者---理音(2004/06/24 21:07:15)


>シグナルハンドラは用意しますが、そこでは何もしないプログラムを書いて
>みました。
>
>NetBSD と Windows の Cygwin では動きましたが、Linux では試していません。
>Linux での結果をお知らせください。

自分の環境(Redhat8)でテストしました。
コンパイルには
#include <sys/types.h>
が、必要でした。その他は特に問題無です。
実行結果は、何もなく即終了しました。
念のため、子プロセスのexitの前にsleepを入れて
ウエイトを入れてみました。その場合はsleepで指定した
時間だけ入力待ちになりその後、終了しました。
意図どおりの動作かと思います。
以上、報告です。


No.2159

解決でしたがすこし発展させて良いでしょうか?
投稿者---理音(2004/06/24 21:51:56)


かずまさんのサンプルをちょこっといじって
テストをしたところ。タイトルに書いた問題は解決でした。
ありがとうございます。
自分の思い込みで間違った認識で実験を仕切れてませんでした。(反省)
>あと、シグナルハンドラを作って終了処理をそこでするというのも
>考えたのですが、何となく全体が見にくくなるのでイヤだなと
>思っています。
この事です。下記のソースとその実行結果その1が解答でした。

さて。
では、親プロセスのループの中の処理をしているときに子が終了
したらどうなるのだろうと思い下のように少しいじりました。
実行結果 その2の用になりました。

こおなると根本的に考えなおさないといけないのかと
思えてきました。
が、けっこう簡単なことに気づいてないきがします。
引続き自分で調べますが何かありましたら宜しくお願いします。

#include <stdio.h>
#include <signal.h>
#include <sys/types.h>

void handler(int n) { }

int main(void)
{
  pid_t result_pid;
  int c, i;
  struct sigaction sa = { handler };
  sigaction(SIGCHLD, &sa, NULL);
  result_pid = fork();
  switch (result_pid) {
  case 0:
    // child
    sleep(2);
    exit(0);
  case -1:
    break;
  default:
    fprintf(stderr,">");
    while ((c = fgetc(stdin)) != 'e' && c != EOF){
      fprintf(stderr,"sleep\n");
      sleep(50);
      fprintf(stderr,">");
    }
    fprintf(stderr,"before wait\n");
    wait(NULL);
    fprintf(stderr,"after wait\n");
    break;
  }
  fprintf(stderr,"kokotte?\n");
  return 0;
}


//-----実行結果 その1
$ ./a.out
before wait
after wait
kokotte?
$
実行して何もしなかった場合の実行結果です。

//-----実行結果 その2
$ ./a.out
> <-実行と同時に">"が表示されすかさずエンター
sleep
>e <-しばらく(2秒くらい)すると">"が表示されて"e"を入力した
before wait
after wait
kokotte?
$
すかさずエンターを押したときの実行結果です。