パフォーマンス上の理由から共有メモリを使用するプログラムを作成しています(代替手段としてのソケットとパイプが評価されており、これらは私のタスクには十分な速度ではありません。一般的に、コピーを含むIPCメソッドは遅すぎます)。共有メモリ領域では、固定サイズの多くの構造体を書いています。構造体を共有メモリに書き込むためのプログラムが1つあり、そこから読み取る多くのクライアントがあります。ただし、クライアントが書き込む必要のある各構造体のメンバーは1つです(参照カウント。アトミックに更新されます)。他のすべてのメンバーは、クライアントに対してのみ読み取る必要があります。
クライアントはその1つのメンバーを変更する必要があるため、共有メモリ領域を読み取り専用としてマップすることはできません。ただし、他のメンバーをいじくり回してはいけません。これらのプログラムはC ++で記述されているため、メモリが破損する可能性があります。理想的には、あるクライアントが別のクライアントをクラッシュさせることは可能な限り困難である必要があります。私はバグのあるクライアントについてのみ心配しており、悪意のあるクライアントについては心配していないので、不完全な解決策は許可されています。
ヘッダーでconstとして使用するメンバーを宣言することで、クライアントによる上書きを阻止することができますが、それでもメモリの破損(バッファオーバーフロー、不正なキャストなど)による上書きを防ぐことはできません。カナリアを挿入することはできますが、それをチェックするための費用を常に支払う必要があります。
参照カウントメンバーを直接保存する代わりに、構造体を読み取り専用のマップされたページに保持しながら、実際のデータへのポインターを別のマップされた書き込み専用ページに保存することができます。これは機能します。ポイントされたデータに書き込もうとすると、OSによってアプリケーションが強制的にクラッシュしますが、ロックフリーアルゴリズムを書き込もうとすると、間接ストレージが望ましくない場合があります。これは、別のレベルの間接参照に従う必要があると、何かができるかどうかが変わる可能性があるためです。アトミックに行われます。
メモリの小さな領域にマークを付けて、それらを書き込むとアプリが爆発するようにする方法はありますか?一部のプラットフォームにはハードウェアウォッチポイントがあり、インラインアセンブリでそれらの1つをアクティブ化できるかもしれませんが、32ビットx86では一度に4つに制限され、それぞれが制限されているため、構造体の一部しかカバーできませんでした4バイトまで。また、プログラムをデバッグするのが面倒になります;)
編集:私はこのかなり目を見張るような紙を見つけましたが、残念ながら、ECCメモリと変更されたLinuxカーネルを使用する必要があります。