投稿者 みどりこぶた  (高校生) 投稿日時 2017/6/10 18:23:48
マルチスレッド、排他制御について。
Threading.Interlocked.Exchangeについて。

幾つかの作業を並行したいと思いマルチスレッドをやってみようと思いました。
調べたところ下記のサイトが分かりやすかったので参考にしました。
http://www.atmarkit.co.jp/ait/articles/0505/25/news113_3.html
そこで、スレッドや変数・オブジェクトのロック取得(?)はコストが高いため条件により使い分けるべきだ、と理解しました。
page3,(3)にThreading.Interlocked.Exchangeとあります。
「変数へ値を設定する」と書いてありますがこの操作はもともとスレッドセーフ(?)なわけではないのでしょうか?

試しに、
    Public Class ClassTest
        Private i As Integer = 0, k As Integer = 1
        Public Sub main()
            Dim th As Threading.Thread
            th = New Threading.Thread(New Threading.ThreadStart(Sub()
                                                                    Do : i = k : Loop
                                                                End Sub)) With {.IsBackground = True}
            th.Start()
            th = New Threading.Thread(New Threading.ThreadStart(Sub()
                                                                    Do : k = i : Loop
                                                                End Sub)) With {.IsBackground = True}
            th.Start()
            MsgBox("ずっと待っていればエラーが...でない…?")
        End Sub
    End Class
という感じでやってみたのですが、一向に例外は吐かれません。
調べたところ、プロセッサのキャッシュやメインメモリとの間で整合性が保証されない(?)とかいうことで、
つまりはその「変数へ値を設定する」という作業を分割できない処理として行う、ことなのかなと理解しました。
そして、上記のプログラムで例外にならないのは、その型が偶然プロセッサが一度に扱えるbit数の範囲内であるから、と理解しました。
従って、環境により異なるため、その偶然はCLI(.net内部?)レベルでは保証されない、と。
しかしそれを保証するThreading.Interlocked.Exchangeなどの関数がある、と。

この認識はあっていますか?
いろいろな型で上記プログラムを試してみましたが、一つも例外にはなりませんでした。skylakeの64bitなのですが古いPCとかだと例外になったりするのですか?



改めて質問をまとめると、複数のスレッドから一つの変数をアクセスする際は、きちんとThreading.Interlocked.Exchangeなどでアクセスするべきなのですか?

vb.net、vs2015で書いてます。勉強とかではなく趣味で、高校生です。常識無いかもしれませんが、指摘いただけると助かります。
前回「初投稿な人」で投稿しましたが、改めました。