2011-06-30 15 views
4

私はを読んでいます.Bjarne StroustrupによるC++のデザインと進化例外処理と非同期信号に関しては、以下のように記述されています:C++例外とシグナルハンドラ

シグナルのようなものを扱うために例外を使うことができますか?ほぼ確実にほとんどのC環境ではありません。問題は、Cがreallantではないmallocのような関数を使用することです。 mallocの途中で割り込みが発生し、例外が発生した場合、例外ハンドラがmallocを再度実行するのを防ぐ方法はありません。呼び出しシーケンス全体のランタイムライブラリは、リエントラントのための要件を中心に設計されている

A C++の実装は、「それが可能な信号は、著者が文で何を意味するのexceptoins

を投げるためになるだろう例外ハンドラがmallocをもう一度実行するのを防ぐ方法はありません。 "どのように関数をリエントラントにすると、シグナルハンドラから例外をスローすることが可能になりますか?

答えて

4

私の意見では、現在のC++ではパーツが本当に意味をなさないということです。

C++では、シグナルはハンドラを実行してから(場合によっては)実行を継続するため、例外をシグナルとして使用する方法はありません。

ただし、C++の例外はこのように動作しません。例外ハンドラに到達すると、スタックはすでにロールバックされており、処理後に「続行」する方法はありません。例外がスローされた後のステートメントに到達する方法はありません。投げられた)。

シグナルは非同期ですが、シグナルが可能な場合には中断せず継続されます(もちろん、シグナルハンドラで行われたことについて注意を払わなくてはならない場合もあります)。例外はプログラムの流れを破壊し、続行不可能です。

論理的なレベルでは2つのアイデアは互換性がなく、ライブラリがリエントラントであるかどうかは関係ありません。

+0

...例外の再開オプションがあった初期のC++の設計であってもよく、あなたがスローされた例外がキャッチされないされた後、プログラムの実行を継続することができなかったことを指摘素晴らしいです。 – Leviathlon

3

たとえば、mallocの呼び出しによってシグナルが発生した場合、そのシグナルハンドラから例外をスローした場合、mallocは例外スローイングロジックによって再び呼び出すことができます。 mallocはリエントラントではないので、定義されていない振る舞いをするでしょう。

シグナルを処理する1つの方法は、シグナル・イベントをイベント・キューにプッシュし、シグナル・ハンドラからただちに戻すことです。それから、イベントループがシグナルイベントを処理するとき、それはシグナルハンドラの制限されたコンテキストにないので、それが望むものを何でもすることができます。

1

実行中に中断され、中断された呼び出しが完了する前に再度呼び出される場合、関数は「リエントラント」です。それを見る別の方法:シグナルハンドラ内からリエントラント関数を呼び出すことができます。シグナルハンドラ内から非リエントラント関数を呼び出すと、すべてのベットがオフになります。シグナルハンドラの中から呼び出されるべき唯一の関数は、再入可能であることが知られている関数です。

mallocはリエントラントではありません。 mallocがkaboomになると、割り当てられたデータを追跡するためにmallocが使用しているグローバルデータを更新する途中でkaboomになったかどうかを知る方法がありません。

シグナルハンドラと例外の別の問題:シグナルハンドラで実行されるコードは、基本的にメインコードとは異なるスレッドで実行されています。 信号をアドレス可能な場合、シグナルハンドラからのリターンは、シグナルが生成されたポイントの直後に戻ります。シグナルハンドラに例外を投げる方法は?これを行うとシグナルハンドラはもう返ってこない!つまり、残りの実行は、シグナルハンドラから効果的に実行されます。今、別の信号が発生したらどうなりますか? 2つのコンセプトは混在しません。再入国はちょうどここの氷山の先端です。