ページ 11

シグナルハンドラが動かない

Posted: 2008年11月20日(木) 14:36
by y
aaa.cの略した中身

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include<signal.h>

//シグナルハンドラ
void xxx_handler(int sig);

void xxx_handler(int sig)
{
~~(いろいろな処理)
}

main(int abc, char def[/url])
{

signal(SIGTERM, &xxx_handler);

~~(いろいろな処理)

for(int i=0;i<hensu;i++){
//bbb.cのsample関数を呼ぶ
sample(int ghi);
}

~~(いろいろな処理)
}


このような感じのソースで
この処理は300秒以上かかってしまうことがあり
SIGTERMで強制終了させられてしまいます。

上記のようにシグナルハンドラを設定しても
なぜかいつもbbb.cの処理中にシグナルハンドラの処理がされないまま
強制終了してしまいます・・・
bbb.cの1回の処理は3秒ほどかかりますが

bbb.cのように他のソースを呼んでいる時は
そっちにもシグナルハンドラは必要ですか?

ちなみにaaa.cとbbb.cはメイクして作成されるバイナリは一つです。
プロセスも一つです。

よろしくお願いいたします。

Re:シグナルハンドラが動かない

Posted: 2008年11月20日(木) 14:56
by 御津凪
http://msdn.microsoft.com/ja-jp/library ... S.80).aspxを見た限りですが…

> 上記のようにシグナルハンドラを設定しても
> なぜかいつもbbb.cの処理中にシグナルハンドラの処理がされないまま
> 強制終了してしまいます・・・

強制終了のシグナルハンドラを処理するなら SIGTERM ではなく、 SIGABRT のような気がします。
( SIGTERM は、終了要求時、 SIGABRT は異常終了時 )

Re:シグナルハンドラが動かない

Posted: 2008年11月20日(木) 18:42
by y
返信ありがとうございます。

300秒経過後に送られてくるシグナルはSIGTERMです。

>signal(SIGTERM, &xxx_handler);

この部分を

int sig;

for(sig=0;sig<256;sig++){
signal(sig, &xxx_handler);
}
と書いて全てのシグナルを登録しても
キャッチできないんです。。。


int sig;

for(sig=0;sig<256;sig++){
signal(sig, &my_handler);
}
while(1){
;
}

上記のようにシグナル登録後に無限ループを入れると
300秒後にSIGTERMをキャッチできたのですが。。。

Re:シグナルハンドラが動かない

Posted: 2008年11月20日(木) 22:49
by たかぎ
処理系不明、ソース不明の状況では正確なことは何もわかりませんが...

ハンドラの中でハンドラを再登録していますか?

Re:シグナルハンドラが動かない

Posted: 2008年11月21日(金) 00:53
by y
レスありがとうございます

>処理系不明、ソース不明の状況では正確なことは何もわかりませんが...

申し訳ございません、
大手企業の社内システムのため詳しいソースは書けません。
SQL文の実行が多く、perlを書き出しCGI生成処理も含まれます。


>ハンドラの中でハンドラを再登録していますか?

はい、もちろんハンドラ処理中に再びシグナルがきた場合も
考えましたが登録してもやはり処理されません。

Re:シグナルハンドラが動かない

Posted: 2008年11月21日(金) 09:50
by たかぎ
> 大手企業の社内システムのため詳しいソースは書けません。

それでは掲示板上で解決するのは困難です。
自己解決してください。

職業柄、個別に相談を受ければ解析しないでもないですが...(もちろん有償で)
まあ、できるだけ自己解決することをお勧めします。

Re:シグナルハンドラが動かない

Posted: 2008年11月21日(金) 13:20
by y
すみません、簡単に質問内容をまとめると

aaa.cにmain関数があり
bbb.cとccc.cの関数を呼び出す処理があり
そこにシグナルハンドラを追加したい場合

aaa.cにだけ
・#include <signal.h>
・シグナルハンドラのプロトタイプ
・シグナルハンドラ
・シグナル登録
を追加して

途中で呼び出される
bbb.cとccc.cの方には何も追加しなくていいんですよね?

ということです。
よろしくお願いいたしますm(_ _)m

Re:シグナルハンドラが動かない

Posted: 2008年11月21日(金) 16:58
by たかぎ
> aaa.cにmain関数があり
> bbb.cとccc.cの関数を呼び出す処理があり
> そこにシグナルハンドラを追加したい場合
>
> aaa.cにだけ
> ・#include <signal.h>
> ・シグナルハンドラのプロトタイプ
> ・シグナルハンドラ
> ・シグナル登録
> を追加して
>
> 途中で呼び出される
> bbb.cとccc.cの方には何も追加しなくていいんですよね?

一般的にはそうです。
ただし、マルチスレッド環境など、標準規格の範疇を超えた処理系特有の事情がある場合はその限りではありません。

Re:シグナルハンドラが動かない

Posted: 2008年11月27日(木) 18:49
by y
たかぎ様、遅くなりましたが返信ありがとうございます。

途中で出される方(仮名bbb.c)にシグナルハンドラを設定してみたところsignal:17(SIGCHLD)をキャッチしました。

子プロセス実行中にシグナルSIGTERMを受信すると親プロセスのハンドラでは
キャッチできませんよね?

つまりシグナルハンドラが動かなかった原因はどこかで子プロセスが起動し、
子プロセス実行中に子プロセスがシグナルで死に、
親プロセス側のハンドラは無反応だったということでしょうかね?

しかし、ソースの中にforkは使っていないのでどこで子プロセスが生成されているのかわかりませんが・・・

Re:シグナルハンドラが動かない

Posted: 2008年11月27日(木) 18:58
by y
あ、ちなみに

>ただし、マルチスレッド環境など、標準規格の範疇を超えた処理系特有の事情がある場合はその限りではありません。

スレッド関連のヘッダはインクルードしていないのでマルチスレッドではないと思います。
貴重なご意見ありがとうございます。