2012-04-07 9 views
3

ロックの仕組みを理解しようとしています。ロックの実装

のは、リソースの利用者がlock()を呼び出し、isLocked場合は、その後lock()戻り偽、真であり、資源のユーザーが持っているC++

class Resource{ 
    public: 
    bool lock(); 
    void unlock(); 
    ... methods to change/read the Resource ... 

    private: 
    bool isLocked; 
} 

に私は本当にシンプルなロックを実装したいとしましょう待つか、何か他のことをしてください。 isLockedがfalseの場合、lock()isLockedをtrueに設定し、trueを返します。呼び出し元は、リソースに必要なものをすべて実行できます。その後、リソース上でunlock()を呼び出してisLockedをfalseに設定します。

しかし、リソースの2人のユーザーが正確に同じ時刻にlock()を呼び出した場合はどうなりますか?このような状況はほとんど起こりませんか?もっと正式には、これはlock()の操作を「アトミック」にすることですが、その単語の意味を正確には分かりません。

答えて

3

"アトミック"は、操作を中断できないことを意味します。つまり、他のスレッド/プロセスの動作に関係なく、その操作のセマンティクスが同じであることを確認できます。あなたは、あなたのlock()コールの何かがおそらく原子的でなければならないでしょう。ほとんどのアーキテクチャでは、原子的な動作が保証された便利な命令が提供されています。プログラミングする上位層で柔軟性を持たせるために、

+0

アトミシティは 'lock()'メソッド全体、または 'lock()'メソッドの特定のステートメントの特徴となるでしょうか?最初のオプションは使いやすくなっています。 – newprogrammer

+0

これはあなたの実装に非常に似ています。本当に基本的なレベルでは、アトミックな単一のマシン命令だけです。あなたは、適切なコードを書くことによって、他のレイヤーを通してそれを拡張することができます。 –

1

まれではありません。これは競合状態と呼ばれ、マルチスレッドコードの多くのバグではありません。

C++標準は実際にスレッド/アトミック性などの概念を持っていないので、です。したがって、OSによって(あるいはおそらくBoost経由で)提供される同期プリミティブに依存する必要があります。


1.これはもはやC++ 11では当てはまりません。

5

従来の標準C++では、ロック変数自体がデータ競合にあるため、独自のロックを実装することはできません。

C++ 11およびC11はアトミックの変数を追加します。この変数は正確にこの目的に使用できます。例えばC++で:ここ

#include <atomic> 

std::atomic<bool> isLocked; 

bool lock() { return !isLocked.exchange(true); } 

void unlock() { isLocked = false; } 

キーは、原子交換と(暗黙の)原子の特別なハードウェア命令を生成し、常にレースフリーです店舗、そしてあなたは通常の変数と「偽」することはできませんです。