11

Mmapはvoid*を返しますが、。は返しませんvolatile void*。mmapを使用して共有メモリをマップしている場合、別のプロセスがそのメモリに書き込んでいる可能性があります。つまり、同じメモリ位置からの2回の後続の読み取りで、異なる値が生成される可能性があります。では、なぜ揮発性のボイド*を返さないのでしょうか。

私の推測では、共有メモリセグメントに排他的に書き込むプロセスがある場合、存在するものを常に正しく理解しているため、揮発性ポインタを介して共有メモリを調べる必要はありません。冗長な読み取りを防ぐためにコンパイラーが行う最適化は、その足元に値を書き込んだり変更したりするものが他にないため、重要ではありません。それとも他の歴史的な理由がありますか?戻るvolatile void*のがより安全なデフォルトであり、この最適化が必要な場合は手動でvoid*にキャストできると言いたくなります。

POSIX mmapの説明:http://opengroup.org/onlinepubs/007908775/xsh/mmap.html

4

6 に答える 6

8

共有メモリの実装は、の使用法のほんの一部ですmmap()。実際、最も一般的な使用法は、匿名とファイルベースの両方のプライベートマッピングを作成することです。これは、共有メモリアクセスに-修飾ポインタを要求することについてのあなたの主張を受け入れたとしてもvolatile、そのような修飾子は一般的な場合には不要であることを意味します。

キャストせずにポインタ型に最終修飾子をいつでも追加できますが、削除することはできません。したがって、現在のmmap()宣言では、次の両方を行うことができます。

volatile char *foo = mmap();  /* I need volatile */

この:

char *bar = mmap();  /* But _I_ do not */

あなたの提案では、一般的なケースのユーザーは揮発性物質を捨てなければならないでしょう。

于 2010-07-09T01:01:38.647 に答える
7

多くのソフトウェアシステムで実行されている深い前提は、ほとんどのプログラマーはシーケンシャルプログラマーであるということです。これは最近変更され始めたばかりです。

mmap共有メモリに関係のない数十の用途があります。プログラマーがマルチスレッドプログラムを作成している場合、安全を確保するために独自の手順を実行する必要があります。各変数をミューテックスで保護することはデフォルトではありません。同様に、別のスレッドが同じ共有メモリセグメントに競合するアクセスを行うことや、そのようにマップされたセグメントに別のスレッドがアクセスできることを想定mmapしないでください。

mmapまた、 asのリターンをマークすることがこれに影響を与えるとは確信していませんvolatile。プログラマーは、マップされた領域へのアクセスの安全性を確保する必要がありますね。

于 2010-07-08T20:25:06.633 に答える
4

揮発性であることは、単一の読み取りのみをカバーします (アーキテクチャによっては 32 ビットまたはその他の可能性があるため、かなり制限されます。多くの場合、複数のマシン語を記述する必要があり、とにかくいくつか導入する必要があります。ある種のロック。

揮発性であっても、同じメモリから異なる値を読み取る 2 つのプロセスを簡単に作成できます。必要なのは、1.プロセスからの読み取りと 2.プロセスからの読み取りの間のナノ秒単位でメモリに書き込むプロセスだけです。 . process (ただし、2 つのプロセスがほぼ同じクロック サイクル内で同じメモリを読み取ることを保証できる場合を除きます。

したがって - mmap() がこれらのことを処理しようとするのはかなり無意味であり、メモリへのアクセスを処理し、必要に応じてポインタを揮発性としてマークする方法をプログラマに任せたほうがよいでしょう - メモリが共有されている場合 - あなた関係するすべての当事者が協力し、お互いに関連してメモリを更新する方法を認識している必要があります-何かはmmapの範囲外であり、自発的なものは解決されません。

于 2010-07-08T20:26:47.287 に答える
1

volatile void *or型void * volatileは無意味です。 a を逆参照できないvoid *ため、型修飾子を指定しても意味がありません。

そして、とにかくchar *データ型へのキャストが必要なため、ボラティリティを指定するのにおそらくそれが適切な場所です。したがって、適切に定義された API は、メモリを足元で変更可能/揮発性とマークする責任を回避します。

とはいえ、全体像のPOVから、私はあなたに同意します.mmapには、コンパイラがこの範囲をキャッシュしないことを示す戻り値の型が必要です。

于 2010-07-08T23:14:11.257 に答える
1

私はvolatileあなたが思っていることをしないと思います。

基本的に、変数の値をレジスターに格納することによって変数を最適化しないようにコンパイラーに指示するだけです。これにより、参照するたびに値を取得するように強制されます。これは、その間に別のスレッド (またはその他のもの) が値を更新できた場合に有効です。

関数は void* を返しますが、更新されないため、volatile と呼んでも意味がありません。ローカルの volatile void* に値を代入しても、何も得られません。

于 2010-07-08T20:20:27.610 に答える
0

おそらくパフォーマンス上の理由からそのように行われ、デフォルトでは何も提供されません。特定のアーキテクチャで書き込み/読み取りがプロセッサによって並べ替えられないことがわかっている場合は、volatile がまったく必要ない場合があります (おそらく他の同期と組み合わせて)。編集: これは単なる例です。メモリにアクセスするたびに再読み取りを強制する必要がないことがわかっている場合は、他にもさまざまなケースがあります。

アクセスされるたびにすべてのアドレスがメモリから読み取られるようにする必要がある場合は、戻り値に const_cast (または C スタイルのキャスト) volatile を自分で使用します。

于 2010-07-08T20:37:18.560 に答える