トップページ⇒tech
17コメント9KB

C++でシグナル処理

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
シグナルコールバック関数をどうすりゃいいんじゃ!
0002デフォルトの名無しさんNGNG
□□□□■□□□□□■□□□□□□□□□□□□□□□□□□□□□
□□□■■□□□□□■□□□□□□□■■■■■■■■■■■■□□
□□■■□□□□□■■■■■■□□□□□□□□□□□□□■■□□
□■■□□■□□□■□□□□■□□□□□□□□□□□□■■□□□
□□■□■■□□■■■□□■■□□□□□□□□□□□■■□□□□
□□□■■□□■■□■■■■□□□□□□□□□□□■■□□□□□
□□■■□□□□□□□■■□□□□□□□□□□□■■□□□□□□
□□■□□□■□□□■■■■□□□□□□□□□□■□□□□□□□
□■■■■■■□□■■□□■■□□□□□□□□□■□□□□□□□
□□□□■□□□■■□□□□■■□□□□□□□□■□□□□□□□
□□■□■□■□□□□■■□□□□□□□□□□□■□□□□□□□
□□■□■□■□□□□□■■□□□□□□□□□□■□□□□□□□
□■■□■□■□□□□□□□□□□□□□□□□□■□□□□□□□
□■□□■□□□□■■■□□□□□□□□□□□□■□□□□□□□
□□□□■□□□□□□■■■□□□□□□□□□□■□□□□□□□
□□□□■□□□□□□□□■■□□□□□□■■■■□□□□□□□
0003デフォルトの名無しさんNGNG
便乗して質問です。signal関数で登録したハンドラは、Cの場合はabort,
exit, およびlongjmpで抜けてもいいことになっているけど、C++の場合は
throwで抜けてもいいの?
0004デフォルトの名無しさんNGNG
ほぼ間違い無く1=3
0005デフォルトの名無しさんNGNG
Windowsだとシグナルってスレッドなの?
0006デフォルトの名無しさんNGNG
おわってますな
0007デフォルトの名無しさんNGNG
シグナルっつーのが何を指しているのかはっきりしないけど、
C++でCのコールバックを扱うときは、ラッパーを作るのがいい。

↓こんな感じ。
class Fred
{
private:
 int id;
 static int handle(Fred *p)
 {
  return p->CallBack();
 }
public:
 Fred()
 {
  id = setup_callback(handle, this);
 }
 ~Fred()
 {
  remove_callback(id);
 }
 virtual int CallBack() = 0;
};
0008デフォルトの名無しさんNGNG
>>1
C++でも別に変わらんよ。

>>3
OK

>>5
コンソールからの割り込みという意味ならyes。別スレッドが自動的に作られる。
ただし、NTだと一つ一つ別スレッドになるが、
9xだと全部同じスレッドになるからシグナルハンドラを抜ける前に
次のシグナルが発生するとシステムごと落ちることがあるので注意。
0009デフォルトの名無しさんNGNG
signalからlongjmpしても良いのか・・
知らんかった。
0010デフォルトの名無しさんNGNG
>>9
Win32 だと SIGFPE のときのみ、条件付きで longjmp() を使っても良いと
MSDN Library に書いてある。逆に SIGFPE 以外では longjmp() を呼んだ
場合の動作は保証されない。

シグナルハンドラで呼べる関数に関しては、かなり制限が厳しくて、Win32
だと

- 入出力
- ヒープ関連
- システムコールを生成する関数

は全て NG となってる。明確には書いてないが、abort(), exit() もダメだと思
われ。Win32 だとシグナルよりも SEH 使った方が良いと思うよ。

Solaris だと、シグナルハンドラから呼べる関数は Async-Signal-Safe 関数
と呼んでいて intro (3) に列挙してある。低レベルの入出力を行うシステム
コールの一部や _exit() は呼べるけど exit() はダメ。

シグナルハンドラから throw した場合の挙動は知らないので、詳しい人がい
たら解説希望。……環境依存っぽい気もするが。
0011デフォルトの名無しさんNGNG
>>10
> シグナルハンドラから throw した場合の挙動は知らないので、詳しい人がい
> たら解説希望。……環境依存っぽい気もするが。

例えばSolarisでは、シグナルハンドラから例外を送出する事は出来ません。
http://docs.sun.com/htmlcoll/coll.675.1/euc-jp/CPPPG/Exception_Handling.html

そもそもC++には
・POSIXのような規格がない
・ANSI/ISOもsignalについて何も言ってない
です。だからC++ではシグナル単独の利用もシステム依存です。

後、WindowsのシグナルとUNIXのシグナルは似て非なるものなので、
>>1はもう少し詳しく要件を説明した方がいい。
00121NGNG
スマーセン。勉強不足と思われ。
Cで書いたlinux上のtcpサーバをC++にしようと思ったりして。
その際のSIGTERMやSIGCHLDをどうしようかと。
Windows?無知だゴルァ!
0013デフォルトの名無しさんNGNG
>>12
ならば、今まで書いていた通りにすりゃいいじゃん。

OOPとの兼ね合いで困っているというなら、
Singletonパターンを覚えるよろし。
生CとC++(きっちりOOP)とのブリッジングには
しばしば必要となるパターンなんで、しっかり覚える。
0014デフォルトの名無しさんNGNG
>>12
SIGCHLD ってことは、もしかして並行処理を fork()で実現 してた?
00151NGNG
>>13
singletonパターン覚える。
>>14
はい。C++にする際に問題化?
確かにクラスメンバ関数からforkするとどうなるか
疑問だったが、そのクラスがそのまま別領域にピーコされる模様?
違うか?あぁ鬱だ。
001614NGNG
>>15
気にしないでくれ。俺の勘違い。

てっきり Linux / C で書いていたのを Win32 / C++ に書き直すって話かと
思って、「それだと fork() 使えないし、設計し直しやろ」とか思った次第。
Linux で C から C++ って話なら、特に問題ないです。
0017デフォルトの名無しさんNGNG
>>15
>クラスメンバ関数からforkするとどうなるか
>疑問だったが、そのクラスがそのまま別領域にヒ゜ーコされる模様?

「クラスがコピーされる(もしかしてクラスじゃなくてObjectと
言いたかったの?)」とか「別領域」とかが
曖昧というかズレた表現なんでちょっと不安だけど、
C++とかのObjectはあくまでProcessの所有物(なんせ単なるメモリ領域)
なので、forkしてもProcessの中でのつじつまは問題ない。
別のProcessの中身として、Objectもコピーされるわけ。

ただ、あるObjectが「OS全体」の中でいきなり数増えても
大丈夫なObjectかどうか?ってのは、心配する必要がある事柄。
Processの外とのつじつまの問題だな。
たとえばFileオブジェクトならどちらか一方をcloseしないと
駄目かも知れない、とか。

まぁそういうのは従来プログラムでも同じだっただろうから、
そういう考え方をOOPの枠組みと絡ませて設計すれば、よし(のハズ)。

あと、forkされちゃったことを個々のObjectに知らせる手段がないと
まずくないか?という議論も、ある。
#という話題が以前、rubyのMLで…
■ このスレッドは過去ログ倉庫に格納されています