揮発性 C++

Hui Fa Xing C



「ユーザー空間アプリケーションの開発者は、常に関連するコンパイラ マニュアルを参照して、さまざまなコンテキストで修飾子がどのように処理されるかを学習する必要があります。これは、volatile キーワードの動作は通常、ハードウェアに依存するものと見なす必要があるためです。オブジェクトが揮発性としてマークされている場合、コンパイラは多くの場合、読み込み操作用に最適化してはならず、レジスタやキャッシュではなく常にプライマリ メモリから取得する必要があると通知されます。ただし、コンパイラーがメモリー位置をレジスターに入れようとすると、ソフトウェアにはほとんど使用できず、ハードウェアでのみ維持されるキャッシュ層が多数あるにもかかわらず、自動的にキャッシュされます。その結果、RAM は、同じメモリ位置からよりも CPU の近くのキャッシュ ラインから何倍も高速にアクセスできます。

volatile 修飾子を使用しないと、最適化が有効になっているときにコードが期待どおりに機能しない可能性があるため、問題が発生する可能性があります。割り込みを利用して有効にすると、コードは計画どおりに機能しません。データは、電源がオンの間、揮発性ストレージにのみ保持されます。電源が取り外されると、データが失われます。

ただし、不揮発性ストレージは電源が切れてもデータを保持します。揮発性ストレージは不揮発性ストレージよりもかなり高速であるため、プロセス情報は一時的に揮発性ストレージに保存されます。不揮発性ストレージとは対照的に、揮発性ストレージは機密データの保護に適しています。これは、電源がオフになっているとデータにアクセスできないためです。揮発性ストレージは、コンピューター システムが数 MB から数 GB しか格納できないため、非常にコストがかかります。」







C++ の揮発性修飾子のプロパティ

ここでは、C++ volatile 修飾子の手段について説明します。変数を宣言すると、修飾子「volatile」が適用されます。これは、値がいつでも変化する可能性があることをコンパイラーに通知するのに役立ちます。揮発性は、以下にリストされている特性のいくつかを持っています。



• volatile キーワードを使用してメモリの割り当てを変更することはできません。



• レジスタの変数はキャッシュできません。





• 割り当てに関しては、値を変更することはできません。

C++ での揮発性修飾子の使用

1. コードは変数の値を変更しませんが、変更する可能性があります。その結果、コンパイラが変数の状態をチェックするたびに、変数から読み取られた最新の値または格納された最新の値と同じであると見なすことができなくなります。むしろ、変数の値をもう一度取得する必要があります。



2. コンパイラは、値を格納する行為を排除する必要はありません。これは、値が揮発性変数に格納されるときに発生する、外部から見ることができる「副作用」であるためです。たとえば、2 つの値が連続して配置される場合、コンパイラは値を 2 回配置する必要があります。

C++ での揮発性修飾子の構文

# 揮発性 data_type variable_name

volatile キーワードは宣言で使用する必要があり、データ型は double、float、または integer を含む任意のデータ型を参照します。最後に、変数の名前を選択します。両方の宣言が有効であるため、いずれかのメソッドを使用して volatile 変数を定義できます。

例: 揮発性修飾子は、C++ で他のスレッドまたは外部アクションによって変更できるオブジェクトを識別するために使用されます

オブジェクトが外部信号または割り込みとして機能するプロシージャによって変更された場合、キャッシュされた状態がその間適切でなくなるため、変更された値を RAM から取得する必要があります。その結果、コンパイラは揮発性オブジェクトへのアクセスを適切に処理します。

#include
#include
#include <スレッド>

標準の使用 :: カウト ;
標準の使用 :: エンドル ;
標準の使用 :: cerr ;
標準の使用 :: 食べる ;

揮発性 整数 = 0 ;

空所 DelayFiveSeconds ( ) {
その間 ( < 3 ) {
眠る ( 200000 ) ;
cerr << '待っている...' << エンドル ;
}
}

空所 増分秒 ( ) {
為に ( 整数 = 0 ; < 5 ; ++ ) {
寝る ( 1 ) ;
cerr << 「増加」 << エンドル ;
= + 1 ;
}
}

整数 主要 ( ) {
構造体 時限開始 { } ;
構造体 時限の終わり { } ;
標準 :: スレッド スレッド1 ;

スレッド1 = 標準 :: スレッド ( 増分秒 ) ;

DelayFiveSeconds ( ) ;

スレッド1。 加入 ( ) ;
戻る EXIT_SUCCESS ;
}


考えられるシナリオを説明するために、データ型「int」の Seconds として宣言され、値 0 が割り当てられた変数を持つ volatile キーワードを使用しました。次に、2 つの関数を作成します。1 つはグローバルな volatile 整数変数を変更する「DelayFiveSeconds」として、もう 1 つは while ループ内で同じ評価を実行する「IncrementSeconds」としてです。この例では、秒数が 3 未満である必要がある場合に、while ループが秒数にわたってループすることを許可していることに注意してください。

条件が満たされると、while ブロックが実行されます。 while ブロック内で、ステートメント「waiting」を出力する unsleep メソッドを呼び出しました。 「IncrementSceonds」関数には for ループがあります。繰り返しの後、sleep メソッドが呼び出され、ステートメント「increment」が出力され、「seconds」変数がインクリメントされます。 「IncrementSeconds」関数の最初の実行は、メイン関数によって作成された別のスレッドによって行われます。その後、「DelayFiveSeconds」メソッドがメイン スレッドによって呼び出され、seconds 変数が値 5 を超えない場合は終了しないループに入ります。

メインスレッドが秒変数の値が変更されたことに気付くとすぐに、別のスレッドが同時にそれを増やし始めているため、メソッドから戻ります。

C++ でスレッド コードを実行するには、コマンド「g++ -pthread –o filename filename.cc」を使用する必要があります。コマンドで「-pthread」をデプロイしないと、コンパイラによって例外がスローされる可能性があります。その結果、揮発性オブジェクトが外部の力によって変更されるまで待機する条件付き待機関数を効果的に作成しました。 volatile 修飾子が削除され、従来のグローバル変数が使用されている場合でも、このコードは同じように機能しますが、更新コード ブロックが別の変換セクションまたは外部シグナル アクションから来る可能性があることに留意することが重要です。

結論

ここでは、理解を深めるために、構文、使用法、および適切な例とともに、C++ での Volatile の概要について説明します。コンパイラは値を予測できないため、C プログラミングでは volatile が重要です。 volatile を利用する主な利点は、ユーザーが変更を要求するたびに、または同じ変数を利用する他のスレッドがアクティブなときに、その値が変化する可能性があることです。