9

私は、シグナルハンドラー内のバイナリサーチツリー(BST)を読み取る必要がある状況にあります(私の知る限り、スレッドベースごとのSIGSEGVシグナルハンドラー)。BST は、アプリケーション内の他のスレッドによって変更できます。

シグナルハンドラはセマフォやミューテックスなどを使用できないため、共有データにアクセスできません。この問題を解決するにはどうすればよいですか? 私のアプリケーションはマルチスレッドで、マルチコア システムで実行されていることに注意してください。

4

4 に答える 4

4

私は2つの非常にクリーンな解決策を見ることができます:

  1. Linux固有:シグナルを処理する専用のスレッドを作成します。signalfd()を使用してシグナルをキャッチします。このようにして、制限されたハンドラーではなく、通常のスレッドでシグナルを処理します。
  2. ポータブル:信号が受信されるまでスリープする専用スレッドも使用します。パイプを使用して、ファイル記述子のペアを作成できます。スレッドは最初の記述子からread(2)を実行でき、シグナルハンドラーでは2番目の記述子にwrite(2)を実行できます。POSIXによれば、シグナルハンドラーでwrite()を使用することは合法です。スレッドがパイプから何かを読み取るとき、スレッドは何らかのアクションを実行する必要があることを認識しています。
于 2012-12-02T16:58:45.617 に答える
4

シグナル ハンドラから共有データにアクセスしないでください。シグナルの詳細については、次の記事を参照してください。

アプリケーション プログラマ向けの Linux シグナル

Linux シグナル処理モデル

Linux シグナルのすべて

これまでのところ、Linux でシグナルを処理する最も安全な方法は signalfd のようです。

于 2011-12-13T16:15:48.490 に答える
3

SH が共有データに直接アクセスできないと仮定すると、間接的にアクセスできる可能性があります。

  1. シグナルハンドラのみが書き込み可能であるが、他の場所から読み取ることができるいくつかのグローバル変数を用意します (同じスレッド内のみであっても)。
  2. SH は、呼び出されたときにフラグを設定します。
  3. スレッドは、BST の変更中でないときにこのフラグをポーリングします。find it が設定されると、元のシグナルに必要な処理を (必要な同期を使用して) 実行し、別のシグナル (SIGUSR1 など) を生成して、処理が完了したことを示します。
  4. THAT信号のSHはフラグをリセットします

SIGSEGV の重複が心配な場合は、カウンターをミックスに追加して追跡してください。(やあ! 独自のセマフォを作成しました!)

ここでの弱点は明らかにポーリングですが、これが始まりです。

于 2011-12-13T16:18:44.950 に答える
1

mmap - フューズファイルシステム (ユーザー空間内) を検討することもできます。

実際には、外部ページャーをサポートしているGnu Hurdの方が満足するでしょう。

また、シグナル ハンドラーでバイナリ サーチ ツリーを読み取るハックは、実際には、移植性がなく、カーネルのバージョンに依存する方法で機能することがよくあります。おそらく、移植性の低い低レベルのトリック ( futexアトミック gcc builtinsなど) を使用したアクセスのシリアル化が機能する可能性があります。NPTL の (マシン固有の) ソース コード、つまり現在の Linux pthread ルーチンを読むと役立つはずです。

etc は実際には Linux シグナルハンドラ内から使用できる可能性pthread_mutex_lockがあります... (おそらくfutexアトミック命令のみを行うため)。

于 2011-12-13T17:53:29.830 に答える