2011-12-21 3 views
2

私は特定のタスクを実行するために使用するブーストスレッドプールを持っています。純粋な仮想関数doWork(int total) = 0;を持つSensorクラスもあります。要求されるたびに、私のメインプロセスは必要なセンサーポインターを取得し、Sensor::doWork(int total)を実行するようにスレッドプールに指示します。信号をキャッチするC++

threadpool->schedule(boost::bind(&Sensor::doWork,this,123456)); 

私は動的に他の誰かが故障セグメンテーション違反になり、コーディングなどを持っている場合ので、それは私のコントロール外にある、型センサのライブラリをロードしています。だから、私の主なプロセスでは、Sensor::doWork(int total)によってスローされたエラーを処理し、スレッドをクリーンアップし、そのセンサーオブジェクトを削除し、エラーが発生した場所と場所をコンソールに通知する方法がありますか?

+0

「信号をキャッチする」は、「セグメンテーションから回復する」とは異なるものです。前者は可能であり、後者はできない。 –

+0

ダイナミックライブラリがsegfaultをスローするのではなく、シグナルをキャッチする方法はありますか? – joshua

+0

標準の '' Cライブラリを使ってシグナルをキャッチすることができます。しかしそれほど重要ではない。重要なのは因果関係です:segfault *はシグナルを引き起こします。しかし、シグナルはセグメンテーションを防ぐことはできません。 –

答えて

0

キャッチSIGSEVに関数コールバックを登録したい場合があります。 Cでは、これはsignalを使って行うことができます。ただし、OSがあなたにSIGSEVを送信したときには、できることはあまりありません(注意する必要はありません)。あなたはあなたのプログラムがどんな状態にあるのか本当に分かりません、私は推測します。例えば、ヒープが壊れました場合は、新しいおよび削除の操作を、そうであっても無地シンプル

std::cout << std::string("hello world") << std::endl; 

文が失敗する可能性があり、ヒープからメモリを割り当てる必要があるため、動作しない場合があります。

ベスト、クリストフ

+0

これは私の今のところですが、正常にそのスレッドを削除してSensorオブジェクトを削除する方法があることを期待していました。 – joshua

1

あなたは、あなたがそれをキャッチした場合でも、SIGSEGVを得た場合に回復する方法はかなりありませんので、あなたのプログラムの状態についての保証はありません。

サードパーティのライブラリを使用していてバグがあり、ライブラリメンテナーがそれを修正しない場合(ソースがない場合)は、サードパーティのライブラリを実行するだけです何らかの手段でメインのバイナリと会話する全く別のバイナリの中から。たとえば、firefoxとplugin-containerを参照してください。

2

ここでセグメンテーションフォルトを処理する唯一の方法は、完全に別のプロセスSensor::doWorkを実行することです。

UNIXではfork(または他の同様の手段)を使用し、子プロセスでSensor::doWorkを実行して、何らかの形で結果を親プロセスに戻します。

同様の手段がWindowsで利用できると仮定します。

編集:私はあなたができることのいくつかを少し肉食していると思った。

ソリューション#1:スレッドと同じ方法でプロセスを処理できます。たとえば、タスク

  • 戻る結果を実行パイプやキューまたはいくつかの類似したオブジェクト
  • 上で渡されるタスクのため

    • 待ちのループにそこに座ってプロセスプールを作成することができますパイプやキュー、または類似のオブジェクト上で実行することができます。

    他のプロセスでタスクを実行しているので、クラッシュすることはありません。このソリューションの主な難点は、実際にプロセス間で通信することです。たぶんboostのプロセスライブラリがそれを助けるでしょう。私は主にこの種のことをPythonで行いました。このモジュールには標準のmultiprocessingモジュールがあります。

    解決策2:異なるプロセスで実行される「安全」と「危険」の部分にアプリケーションを分けることができます。 「危険な」部分は、Sensor::doWorkの方法とそのプロセスでやりたいことがある他のものを実行しますが、クラッシュした場合に自発的に失われても問題はありません。 「安全な」部分は、あなたが失うことができない貴重な情報を扱い、「危険な」部分を監視し、子供が墜落したときにいくつかの回復操作を実行します。そして、もちろん、あなたが安全な部分でやりたいと思う他の仕事があれば、

  • +0

    プール内でこれを行う方法があるので、私は子プロセスを常に設定しておらず、終了するのを待っていませんか?これは時間の影響を受けやすい問題ですので、そうするには時間がかかると感じています。 – joshua

    +0

    遅すぎるとは思わないでください。実際に試してみてください。そしてあなたはそれを設定して、子プロセスを1つしか持たず、クラッシュしない限り再利用し続けることができます。しかし、とにかく、あなたはあなたのプロセスを破壊する 'doWork'呼び出しについて非常に心配しているようです。 – Hurkyl

    +0

    それはさておき、あなたが本当に求めている質問は、あなたのプロセスを 'doWork'呼び出しによって壊さないように保護する方法だと思います。別のプロセスで 'doWork'を実行することは、その保護を提供する唯一の合理的な方法だと私は思います。セグメンテーションフォルトは、偶発的には、通常、ある種の腐敗の*症状*です。あなたがそれをキャッチしても、あなたのプログラムはまだ壊れている可能性があります。 – Hurkyl

    関連する問題