2017-02-14 37 views
3

私はstd::mutexstd::lock_guardを使用しようとしているので、スレッドセーフな関数呼び出しをスレッドセーフにする必要があります。現在のコードは次のようになります。静的なmutexで静的なlock_guardもありますか?

int myFunc(int value){ 
    static std::mutex m; 
    std::lock_guard lock(m); 
    auto a = unsafe_call(value); 
    return a; 
} 

unsafe_call()はスレッドに不安全な関数です。私はmutexの周りにstaticを置いています。なぜなら、関数は別々の呼び出しごとに異なるmutexを持つからです。

lock_guard私が知りたいことは、私が私の同僚に言われたように、mutexが静的なものであるためです。私はlock_guardを単純な0​​と.unlock()と呼んでいると考えているので、なぜ私はこれを行う必要があるのか​​わかりませんが、同僚の提案は私を混乱させています。

+8

静的な 'lock_guard'の目的を無効にする – NathanOliver

+0

静的な' std :: mutex'はうまくいくようです(どこかに保存しなければならないかもしれませんが、よりエルエルギィに保存する必要があります)が、Nathanは 'lock_guard'のctorロックmutexとdtorがロックを解除します。ロックが静的ロックの場合、ミューテックスは決してロック解除されません。 – hauron

+4

あなたの同僚は、話していることを知らない。 'lock_guard'がどのように動作するかについてのあなたの理解は、彼らのものよりも優れています。 – WhozCraig

答えて

5

mutexは静的なものであるため、lock_guardも静的にする必要があります。私は同僚の一部に言われたとおりです。

NO

2つのスレッドがあなたの関数を入力し、両方が同じstatic std::mutex mを得るシナリオを検討してください。 1つはロックしようとし、もう1つはチャンスを得ることはありません[1]。さらに、最初の関数が終了すると、lock_guardは静的記憶域であり、スコープは有効であるためデストラクタは呼び出されないため、mutexのロックを実際に解除することはありません。

[1] - 一度だけガードが静的である場合に実行されるだろうCTORでのstd :: lock_guardロックは、2番目のスレッドがさえをロックしようとしないだろう - コメントで@Slavaによって修正として。

+1

で更新された解答あなたの説明は間違っています。 – Slava

+0

@Slavaは私を許しています。それは私がどこかで読んでいる間に理解したものです。あなたは私を訂正してもらえますか –

+0

'std :: lock_guard'はctorでロックします。これは、ガードが静的であれば一度だけ実行され、2番目のスレッドはロックしようとしません。 – Slava

2

また、mutexが静的なものであるため、私はlock_guardを静的にする必要があります。これは、私の同僚の一部に言われたとおりです。

同僚はlock_guard(この場合はミューテックス)リソースを制御するためにRAIIメカニズムを使用して、それが目的だ完全に台無しにしてしまうことが静的作っている、完全に間違っている - ミューテックスは、関数の最初の実行時に一度ロックされ、解放されるだろうプログラムが終了するときにのみ、つまり効果的にmutexをまったく使用しないことになります。

+0

RAIIメカニズムは何ですか? –

+0

@hg_gitはリンク – Slava

1

私はシンプル.lock().unlock()コールするlock_guard考えるが、同僚からの提案は私を混乱されているので、私は、私はこれを行う必要がある理由が表示されません。

この提案はナンセンスなIMOであり、あなたは正当にそれについて混乱しています。

std::lock_guardの目的は、特定のスコープ内で保証された(および例外に対して堅牢な)mutexのロック/ロック解除を行うことです。これは、変数スコープが残っているときに呼び出されることが保証されているデストラクタ関数の動作を使用して行われます。
staticの変数の場合、デストラクタはプロセス寿命の終わりに呼び出されるのが最良です。したがって、ミューテックスは、最初の呼び出しスレッドによってプロセス全体でロックされます。

グローバルスコープは、static lock_guardと表示されるため、正確であるとは思えません。

あなたの同僚は間違っています。

関連する問題