Quando usar lock vs MemoryBarrier em .NET
-
18-09-2019 - |
Pergunta
No .NET o lock
palavra-chave é açúcar sintático ao redor Monitor.Enter
e Monitor.Exit
, então você poderia dizer que este código
lock(locker)
{
// Do something
}
é o mesmo que
Monitor.Enter(locker);
try
{
// Do Something
}
finally
{
Monitor.Exit(locker);
}
No entanto, o framework .NET também inclui o MemoryBarrier
classe que funciona de maneira semelhante
Thread.MemoryBarrier();
//Do something
Thread.MemoryBarrier();
Estou confuso sobre quando eu gostaria de usar Thread.MemoryBarrier
sobre o lock
/Monitor
versão?Fico ainda mais confuso com um tutorial de threading que afirma que eles funcionam da mesma forma.
Pelo que posso ver, a diferença visível é não precisar de um objeto de bloqueio, o que acho que usar Monitor
você poderia fazer algo entre tópicos onde MemoryBarrier
está em um único thread.
Meu instinto está me dizendo que outra diferença importante é MemoryBarrier
é apenas para variáveis e não para métodos.
Por último, isso não está relacionado à questão existente Quando usar ‘volátil’ ou ‘Thread.MemoryBarrier()’ no código de bloqueio threadsafe?(C#), já que se concentra no volatile
palavra-chave que eu entendo seu uso.
Solução
Na minha opinião, você quase deveria nunca usar Thread.MemoryBarrier
.Isto é usado para sem bloqueio código - garantindo que as alterações feitas em um thread sejam visíveis para outro sem incorrer no custo de um bloqueio.Isso acontece não controlar a sincronização de threads, ao contrário lock
.Não vejo onde no tutorial do Joe ele diz isso MemoryBarrier
"funciona da mesma forma" que lock
.Você poderia explicar de onde exatamente você está tirando essa impressão?
Na minha opinião, o código livre de bloqueio de baixo nível é muito difícil para quase qualquer pessoa, exceto os desenvolvedores cuja principal proficiência é a simultaneidade.Se eu quiser escrever algum código sem bloqueio, usarei blocos de construção de nível superior construído por esses desenvolvedores (como Extensões Paralelas no .NET 4.0) em vez de tentar criar o meu próprio.
Apenas como exemplo, recentemente tive meus olhos abertos para o significado preciso de volatile
qual não é "sempre leia da memória principal, sempre escreva diretamente na memória principal".(Meu próprio tutorial de threading ainda tem essa explicação no momento - algo que preciso corrigir em algum momento.) É muito mais sutil do que isso.Isso significa que alguns dos meus usos anteriores de volatile
pode muito bem estar incorreto.