- ベストアンサー
SIGALRMでプロセス終了
SIGALRMが跳ねると登録してあるコールバック関数が呼ばれるのですが、その関数の処理後にプロセスが終了してしまいます。その理由が知りたいので教えてください。 実行してみると -------------------------------- callback_start .....コールバック関数のprint分を実行 callback_end .....コールバック関数のprint分を実行 アラームクロック -------------------------------- 3行目のメッセージがどこからか出力されます。 ちなみにdbxでコールバック関数を止めてみると 関数内の1行目でnextを実行すると -------------------------------- シグナル 14 (SIGALRM) で終了中 -------------------------------- と出力されます。 マシンはSolaris8でC言語です。 シグナルのマスク処理等はなにもなく、signal()関数が呼ばれているだけです。 よろしくお願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
コールバック関数の登録は、どのようにされましたでしょうか。 signal関数で登録した場合は、SIGALRMにより、この関数が呼ばれると、デフォルト状態に戻ります。従って、2回目のSIGALRMが発生したときに、異常終了します。 コールバック関数を、CallBackとすると、 signal(SIGALRM,CallBack); ・・ ・・ void Callback(int sig) { //printf文 } のようになっているとき、 void Callback(int sig) { signal(SIGALRM,CallBack); //これを追加 //printf文 } このことにより、SIGALRMが発生する都度、シグナルハンドラーが再設定されます。これで、終了しなくなるはずです。 (但し、この方法はシグナルが速射された場合は役に立ちませんが、SIGALRMが速射されなければ、そこそこ使えます。速射に対応する恒久的な手段は、sigactionになりますが、それを必要とする場合はその旨補足してください)
その他の回答 (2)
- tatsu99
- ベストアンサー率52% (391/751)
>速射とはどの程度の速さと判断すればよろしいでしょうか?当方のsetitimerの設定は1秒ですので速射では無いでしょうが、参考までに教えてください。 シグナルハンドラーが呼び出されてから、シグナルハンドラーの再設定を行うときまでに、再度、シグナルが発生すると、signalを使う方法では、対処できません。 下記の例では、 void Callback(int sig) { ・・・ここで、また、SIGALRMが発生すると、この方式では、対処不能。 signal(SIGALRM,CallBack); //これを追加 //printf文 } 上記の状態が、発生しなければ、問題ありません。 上記の状態が発生するのが、具体的に、何msecかは不明ですが、1秒なら、問題ありません。
お礼
ご回答ありがとうございます。 1秒と書きましたが、マスクをして解除されるまで十数秒かかりますので、上記の方法では問題があるようです。 sigaction()に切り替えることで問題は発生しなくなりました。ありがとうございました。
- oldroot2005
- ベストアンサー率66% (68/103)
signal(2) はよろしくない性質がいろいろあるので、sigaction(2) を使った方が良いでしょう。使い分けるのではなく、sigaction(2) が使えるなら常にそちらを使った方が良い、ということです。
お礼
ご回答ありがとうございます。 今後はsigaction()を使うようにします。 ありがとうございました。
お礼
回答ありがとうございます。 速射の場合には役に立たないというのはどういうことになるのでしょうか? signal()を使うのを避けてsigaction()を使ったほうが良いと書かれているのをどこかで呼んだことがあります。この2つは使い分けることになるのでしょうか。 その場合、 速射とはどの程度の速さと判断すればよろしいでしょうか?当方のsetitimerの設定は1秒ですので速射では無いでしょうが、参考までに教えてください。