2011-07-23 16 views
14

私はQtフレームワークを使用している簡単なプログラムを1つ持っています。 QProcessを使用してRARを実行し、いくつかのファイルを圧縮します。私のプログラムでは、私はSIGINTをキャッチしていますし、それがoccuresたときに私のコードで何かをやって:RARプロセスが実行された場合子プロセスは親のSIGINTを受け取ります

signal(SIGINT, &unix_handler); 

SIGINTはoccures、私がチェックし、そうでない場合、私はそれを待っています...問題は(私は)RARプロセスも自分のプログラム用のSIGINTを取得し、すべてのファイルを圧縮する前に終了するということです。

プログラムが受信したときにSIGINTを受信しないようにRARプロセスを実行する方法はありますか?

ありがとうございました

+0

どのオペレーティングシステムですか? – Nemo

+0

現在、私はDebian 5.0.8でこれをテストしています – xx77aBs

答えて

25

UNIXシステムでCtrl-cを使用してSIGINTを生成している場合、信号はprocess group全体に送信されています。

setpgidまたはsetsidを使用して、制御ターミナルによって生成されたシグナルを受信しないように、子プロセスを別のプロセスグループに入れる必要があります。

[編集]

は慎重setpgidページの根拠セクションを必ずお読みください。潜在的な競争条件をすべてここに詰め込むのはちょっと難しいことです。

は何 SIGINTがあなたの子プロセスに配信されません100%を保証するために、あなたはこのような何かをする必要があります。

#define CHECK(x) if(!(x)) { perror(#x " failed"); abort(); /* or whatever */ } 
/* Block SIGINT. */ 
sigset_t mask, omask; 
sigemptyset(&mask); 
sigaddset(&mask, SIGINT); 
CHECK(sigprocmask(SIG_BLOCK, &mask, &omask) == 0); 

/* Spawn child. */ 
pid_t child_pid = fork(); 
CHECK(child_pid >= 0); 
if (child_pid == 0) { 
    /* Child */ 
    CHECK(setpgid(0, 0) == 0); 
    execl(...); 
    abort(); 
} 
/* Parent */ 
if (setpgid(child_pid, child_pid) < 0 && errno != EACCES) 
    abort(); /* or whatever */ 
/* Unblock SIGINT */ 
CHECK(sigprocmask(SIG_SETMASK, &omask, NULL) == 0); 

厳密に言えば、これらのステップの一つ一つが必要です。 forkの呼び出しの直後にユーザーがCtrl-Cを押すと、信号をブロックする必要があります。親が何かをする時間がある前にexeclが起こった場合は、子供の中でsetpgidに電話する必要があります。親の親のが実行され、誰かが子のに何かする時間がある前にCtrl-Cを押すと、setpgidを親に呼び出す必要があります。

上記のシーケンスは不器用ですが、競合条件の100%を処理します。

+0

ありがとうございます。私はそれが私の問題に対する答えだと思う。私はできるだけ早く試してみます;) – xx77aBs

+0

これはうまくいきました。私はちょうど正しいインクルードとこの行を追加しました:setpgid(rar.pid()、0); – xx77aBs

+0

問題ありません。'setpgid'は競合条件に悩まされていることに注意してください。正しく使用するにはちょっと微妙です。私はより完全に私の答えを更新しました。 – Nemo

0

あなたのハンドラでは何をしていますか? Unixシグナルハンドラから安全に呼び出せるQt関数しかありません。ドキュメント内のThis pageは、それらが何であるかを識別します。

主な問題は、ハンドラがメインのQtイベントスレッドの外側で実行されることです。このページでは、これに対処する方法も提案しています。私は、ハンドラがカスタムイベントをアプリケーションに「ポスト」してそのように処理する方が好きです。カスタムイベントの実装方法を説明したhereを投稿しました。

+0

このページをありがとう、私はそれを知らなかった。私はただ終了してスレッドを待ってから、アプリケーションを終了します。それはRARを除くすべてのために働くので、私はそれが問題だとは思わない。しかし、私はこのページを読むでしょう。再度ありがとう – xx77aBs

関連する問題