dポイントプレゼントキャンペーン実施中!

C++のvolatileについて

volatileはマルチスレッドやメモリマップドi/oに使われるようですが、volatileの概念や使い方がさっぱり分かりません。
Webサイトで調べてもあまり意味が分からないし、参考になるサイトがなかなか見つからないので、ここで質問しました。

volatileでマルチスレッドを使った例のコードを教えてください。

また、以下のコードでは、「while文の中でloopの値を変更していないので、これはシングルスレッドでは単なる無限ループになり、あまり意味のない処理になる。ところが、マルチスレッドの場合は別のスレッドからloopの値を変更される可能性があるため、意味のある処理になる」というものですが、これはどういうことでしょうか。

-------------------------
bool loop;

void Hoge(){
loop=true;

int n=0;
while(loop){
++n;
}
cout << n << endl;
}
-------------------------
上記のコードは、そのままでは無限ループになる。マルチスレッドにしてloopの値を変更するにはどうしたら良いでしょうか。

A 回答 (4件)

volatile は「処理系には認識できない方法で値が変化することがあるので, 極端な最適化をしてはならない」というヒントです. 挙がっている例だと, 「while文の中でloopの値を変更していない」ので処理系が「while の条件は loop って書いてあるけど, これは true にしたまま変えてないから loop を true で置き換えちゃえ」とするかもしれません. ところが volatile をつけて loop を宣言すると「ここには書いてないけど loop の値は変化するかもしれない」ということがわかるので, 上のような極端な最適化をすることはなくなります.


「プログラムの実行パスからはわからない値の変化」なので, マルチスレッドでなくとも signal とかが絡むと意味を持ちます.
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。

参考にします。

お礼日時:2010/12/02 01:39

#2です。

一箇所訂正です。

> 関数内ではloopの値が変わらない

ではなく

> ループ内ではloopの値が変わらない

です。
    • good
    • 0

「どうやってマルチスレッドプログラムにするか」の部分は置いておきます。


別途それなりの量の勉強が必要な箇所ですからここで全部を行うのは無理ですし、スレッド関係はOSのAPI依存でもあるので。

で、質問のコードに以下のコードを付加します。

void Fuga()
{
loop = false;
}

このコードで、HogeとFugaをそれぞれ別スレッドで動かすことでループから脱出するようにできます。

が。本題のvolatileの出番はここからです。
Hogeのwhileループは、コンパイラによっては最適化されて「関数内ではloopの値が変わらない」ので無条件ループ(while(1)と同じ)に置き換えられてしまう事があります。
こうなってしまうと、外でloopの中身を変更してもHogeが見ていないのでループを脱出できなくなってしまいます。
volatile修飾子は、この最適化を抑止して常にちゃんとloopの値を見るコードを生成するようコンパイラに指示するためのものなのです。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。

参考にします。

お礼日時:2010/12/02 01:38

>これはどういうことでしょうか。


アセンブラコードを確認すればわかると思いますが
このようなコードを書いた場合
volatileにしないと場合によって最適化されて
値のチェックを行わないコードが吐き出されます
(初回に読み込んで永久ループ)

その為他の所で値を変えてもループから抜けない
といったことが起こりえます

volatileにすることでそういったことを避けられます
(都度値をチェック)

>どうしたら良いでしょうか。
volatile bool loop; に変える
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。

参考にします。

お礼日時:2010/12/02 01:38

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!