4

この「ステータス」オブジェクトを 2 つのスレッド間で安全に共有できますか?

    private bool status = false;

    private void uiNewThread_bootloaderStartIdSetupAuto()
    {
        while (status)
            ;
    }

上は、下の UI から起動される新しいスレッドです。

    private void uiBtnBootloaderStartIdSetupAuto_Click(object sender, EventArgs e)
    {
        if (MessageBox.Show("ID will be setup starting from 1 to 16. \n\nAfter pressing 'YES', press the orange button one-by-one on the nodes.\nThe first pressed node will have number 1, the next number 2, and so on... \n\nWhen done, hit DONE button.", "ID setup", MessageBoxButtons.YesNo) == DialogResult.Yes)
        {
            status = true;
            Thread transmitConfig = new Thread(new ThreadStart(uiNewThread_bootloaderStartIdSetupAuto)); //close port in new thread to avoid 
            transmitConfig.Start();
        }
        else
        {
            Log(LogMsgType.Normal, "User cancelled");
            status = false;            
        }
    }
4

2 に答える 2

4

コンパイラまたはCPUによって実行されるキャッシュや並べ替えなどの最適化により、コードが破損する可能性があります。volatileこれを防ぐために、フィールドを宣言する必要があります。

private volatile bool status = false;

問題が発生する可能性のある例は、2つのスレッドが異なるコアで実行statusされている場合、ポーリングスレッドが実行されているコアによっての値がCPUレジスタにキャッシュされ、他のスレッドによって更新された値が表示されない可能性があることです。

リリースモードでアプリをビルドしてみてください。この効果が見られるはずです。

于 2012-07-17T09:51:00.730 に答える
0

変数をロックするだけの方が良いかもしれません。

private static readonly object _lock = new Object();

....

lock(_lock){
//access to boolean variable etc.
}

もう1つの可能性は、ブール値をLazyでラップすることであり、内部値へのアクセスはスレッドセーフです。

値の読み取りと更新にロックフリーメカニズムを使用する場合は、Interlockedクラスのメソッドの使用を検討できます。

ここの情報:

System.Threading.Interlocked

于 2012-07-17T09:54:48.737 に答える