5

アンマウントできるファイルで mmap() を実行しています (ファイルは、ユーザーがいつでも削除できる USB デバイス上にあります)。ファイルがアンマウントされている場合、アプリケーションがクラッシュし、要素にアクセスしようとしますバッファ内。

これに対する解決策はありますか?

4

4 に答える 4

8

まず第一に、これは「最適化された読み取り」などとして不必要に使用しないため の良い議論として役立つはずだと言いたいです。mmapデバイスの削除とは別に、他のプロセスによるファイルの切り捨てなどの問題により、アクセスが失敗する可能性がありSIGBUSます。

本当に を使用する必要がある場合はmmap、 のシグナル ハンドラをインストールできますSIGBUS。そのタスクは基本的に次のとおりです。

  1. 発生したグローバル (またはプログラムがマルチスレッドの場合はスレッドローカル) フラグを設定しSIGBUSて、障害のあるコードが認識できるようにします。
  2. mmapwithを呼び出してMAP_FIXED、新しい匿名ページを障害のあるページの上にマップします。必要に応じて、マップにアクセスするコードによってエラーとして認識されるデータを入力します。これにより、ステップ 1 が不要になる可能性があります。

jmp_buf別の方法として、マップにアクセスする前にグローバル (またはスレッド ローカル) を設定し、シグナル ハンドラで単に を呼び出すようにしますlongjmp

どちらも async-signal-safe ではありませんが、問題の は非同期シグナルではないことに注意しmmaplongjmpくださいSIGBUS(ただし、 のような非同期シグナルセーフでないライブラリ関数内でフォールト アクセスが発生した場合は、非同期シグナルと見なす必要がありますsscanf)。マップにアクセスするライブラリ関数ではなく、独自のコードである限り、どちらでも安全です。またmmap、ほとんど/すべての実世界の実装で非同期シグナルセーフであるため、正式に正しくなくても、実際には最初のソリューションで問題ないはずです。

于 2012-10-15T13:21:56.990 に答える
3

mmap最も簡単な方法は、 ed アドレスに対応するメモリ位置へのアクセスをチェックするシグナル ハンドラを設定することです。

ハンドラーはシグナルのアドレスに対応するパラメーターで情報を受け取るため、単純なハンドラーsigactionではなく、シグナル ハンドラーの形式を使用します。これは、 ed ファイルのアドレス範囲内にあるかどうかを確認できます。signalsigactionstruct __siginfo *mmap

mmapデータのバッファ読み取り/書き込みの複雑さに対処したくない場合に最適ですが、何かがうまくいかないために 1 つの形式のエラー (シグナル) しか得られません。read/writeメカニズムを使用すると、 を取得して、何が起こったかを判断できますerrno。この場合、これは開発者の選択です。

setjmp信号を受信した後に場所にジャンプするには、 and longjmp/を使用する必要があります-この質問siglongjmpでこれを使用する方法を参照してください

于 2012-10-15T10:56:36.777 に答える
-2

http://linux.die.net/man/7/inotifyを使用して、ファイル、ディレクトリの変更に関する通知を受け取ることができます。IN_DELETEの使用を検討してください。

于 2012-10-15T13:34:40.127 に答える
-2

利用できないファイルにはアクセスしないでください。ファイルが残っているか確認するか、アンマウントできないファイルを使用してください。

于 2012-10-15T10:25:22.980 に答える