2011-02-03 32 views
2

現在、.NETでSystem :: Threading :: Interlockedクラスを使用してアトミック操作のみを使用しているC++ .netでスレッド同期を達成しようとしています。私はマルチスレッドではあまり経験がありません。私はロックレスのスレッド同期を使用しようとしています。現在、スレッド間で共有する必要がある静的変数を含む設定と呼ばれるクラスを作成しました。私は静的データメンバを設定する静的関数と静的データメンバを読み込む静的関数の2つを作成しました。現在のところ、これは私の静的同期関数のようなものです。 2つ以上のスレッドが同時にこの関数を入力すると、whileループで永遠にスタックすることがありますが、2つのスレッドだけがこの関数を必要とすることを理解しています、GUIスレッドと設定とディスパッチを読み込むメインスレッドワーカースレッドに作業します。アトミック操作のみを使用するC++/CLIのスレッド同期


//object is handle to instance of settings class that also contains non-static 
//members that will contain each threads copy of the data. 
void Settings::SetStaticVariables(Settings ^object) 
{ 
    int returnvalue; 

    //canchange variable is a static integer of the class "Settings" 
    returnvalue = Threading::Interlocked::Increment(Settings::canchange); 
    if(returnvalue > 1) 
    { 
     while(Settings::canchange > 1) 
     { 
      //perhaps eventually I will find an alternative to telling the thread 
      //to sleep for a defined amount of time, maybe when I learn how to use events 
      //for now this will do, speed is not very important for this data sync as 
      //it does not occure often 
      Threading::Thread::Sleep(50); 
     } 
    } 
    //data synchronization of static members here 

    //decrement allowing waiting threads to exit while loop 
    Threading::Interlocked::Decrement(Settings::canchange); 
}; 

私の質問は、私が期待したり欠陥が同期のために、この全体的なアイデアである午前ものを私に与えることはありません不備が何も見えないのですか?

+3

で次のようになります「私は、マルチスレッドでのすべての非常に経験豊富ではないと私はロックレススレッドの同期を使用しようとしています。」これは不十分に終了する可能性が高いです。正しいマルチスレッドコードを書くことは難しく、そうすることでロックフリーになるのは難しくなります。ロックを使用しようとしましたが、ロックが実際のパフォーマンスのホットスポットかどうかを確認するためにプロファイルしましたか? –

+0

私はロックを使用しようとはしませんでしたが、コードのこのセクションでのパフォーマンスは重要ではないので、ロックを使用することができます。それが最善のルートだと思うなら、間違いなく使うことができます。ロックレスの同期を経験した方が良いと思ったのは、マルチスレッドに関する記事を読んでいたからです。ロックをできるだけ少なくすることが最善の方法です。また、私は最終的にスピードが問題になるコードを作成しようとしますが、今はロックに精通していると思います。 – contrapsych

+0

@ジェームス:+1。もしできれば+10。 @ジェイク:ロックを避けることは一般的には良いことですが、もっと重要なのはロックフリーの同期を避けるというルールです - 具体的には、「あなたが何十年もの専門家でなければロックフリーの同期コードを書いてはいけません。マルチスレッドのプログラマーと高度な数学者があなたの仕事をチェックできる準備ができています」 –

答えて

2

これは、最大2つのスレッドだけが安全であると判断できる場合は、マルチスレッドをよく見ています。ロックフリーの技術を勉強することを人々が妨げないようにしてください。

増分の代わりにInterlockedExchangeを使用すると、> = 2スレッドでデッドロックが発生する可能性があります。しかし、このアルゴリズムはロックフリーのプログラミングではなく、独自のロックを実装しています。もちろんこれは、ライブラリーをロックするクラス(Monitorとフレンド)によって既に解決されている多くのパフォーマンスと正確性の問題にぶつかることを意味します。ここで

はそれがInterlocked::Exchange

// try to acquire lock 
while (0 != Interlocked::Exchange(Settings::canchange, 1)) 
{ 
    Thread::Sleep(50); 
} 

MemoryBarrierAcquire(); 

// update shared variables 

// flush cached writes 
MemoryBarrierRelease(); 
// unlock 
Settings::canchange = 0; 
+0

アドバイスありがとうが、私はそれらを使用して一般的に私が今よりもマルチスレッドを理解するまで、私はロックなしで試してみません。また、もしあなたができれば、自分のロックを実装したものとは違って、「ロックフリー」マルチスレッドとはどのくらい正確ですか(LOLの質問をする前にそれをよく理解していたはずです)。 – contrapsych

+0

@JAKE:本当にロックフリーなプログラミングの例として、Win32 ['SList API'](http://msdn.microsoft.com/en-us/library/ms684121.aspx)を検討してください。マルチプロデューサのシングルコンシューマスレッドセーフキュー。私は実際にC++で同じデータ構造を実装していますが、インターロックされたAPIを使用しています。違いはC++の魔法のおかげでタイプセーフである点です。不変性は、ロックフリープログラミングにおいて重要な役割を果たします。 –

+0

私はそれがしばらくしていることは知っていますが、1つのスレッドで変更を加えた場合、メモリバリヤーはプロセッサー・キャッシュもフラッシュするか、キャッシュの一貫性を維持するために揮発性の書き込みと読み取りを行う必要がありますか?それともプロセッサによって自動的に維持されていますか? – contrapsych

関連する問題