Alguém pode explicar simplesmente o que é contenção de thread?
Eu pesquisei, mas não consigo encontrar uma explicação simples.
multithreading
language-agnostic
Tony o Leão
fonte
fonte
Respostas:
Essencialmente, a contenção de thread é uma condição em que uma thread está esperando por um bloqueio / objeto que está sendo mantido por outra thread. Portanto, esse thread em espera não pode usar esse objeto até que o outro thread desbloqueie esse objeto específico.
fonte
Várias respostas parecem se concentrar na contenção de bloqueio, mas os bloqueios não são os únicos recursos nos quais a contenção pode ser experimentada. A contenção é simplesmente quando dois encadeamentos tentam acessar o mesmo recurso ou recursos relacionados de tal forma que pelo menos um dos encadeamentos em disputa é executado mais lentamente do que se os outros encadeamentos não estivessem em execução.
O exemplo mais óbvio de contenção está em uma fechadura. Se o encadeamento A tiver um bloqueio e o encadeamento B quiser adquirir esse mesmo bloqueio, o encadeamento B terá que esperar até que o encadeamento A libere o bloqueio.
Agora, isso é específico da plataforma, mas o encadeamento pode sofrer lentidão mesmo se nunca tiver que esperar que o outro encadeamento libere o bloqueio! Isso ocorre porque um bloqueio protege alguns tipos de dados, e os próprios dados também serão contestados.
Por exemplo, considere um thread que adquire um bloqueio, modifica um objeto, libera o bloqueio e faz algumas outras coisas. Se dois encadeamentos estiverem fazendo isso, mesmo que nunca lutem pelo bloqueio, os encadeamentos podem ser executados muito mais lentamente do que se apenas um deles estivesse em execução.
Por quê? Digamos que cada thread esteja executando em seu próprio núcleo em uma CPU x86 moderna e os núcleos não compartilham um cache L2. Com apenas um thread, o objeto pode permanecer no cache L2 a maior parte do tempo. Com os dois threads em execução, cada vez que um thread modifica o objeto, o outro thread descobrirá que os dados não estão em seu cache L2 porque a outra CPU invalidou a linha do cache. Em um Pentium D, por exemplo, isso fará com que o código seja executado na velocidade FSB, que é muito menor do que a velocidade do cache L2.
Uma vez que a contenção pode ocorrer mesmo que o bloqueio não seja disputado, a contenção também pode ocorrer quando não há bloqueio. Por exemplo, digamos que sua CPU suporte um incremento atômico de uma variável de 32 bits. Se um thread continua aumentando e diminuindo uma variável, a variável ficará quente no cache a maior parte do tempo. Se dois encadeamentos o fizerem, seus caches disputarão a propriedade da memória que contém essa variável, e muitos acessos serão mais lentos, pois o protocolo de coerência do cache opera para garantir a propriedade de cada núcleo da linha do cache.
Ironicamente, os bloqueios normalmente reduzem a contenção. Por quê? Porque sem um bloqueio, dois threads podem operar no mesmo objeto ou coleção e causar muita contenção (por exemplo, existem filas livres de bloqueio). Os bloqueios tendem a cancelar a programação de encadeamentos concorrentes, permitindo que encadeamentos não concorrentes sejam executados. Se o encadeamento A mantém um bloqueio e o encadeamento B deseja esse mesmo bloqueio, a implementação pode executar o encadeamento C em vez disso. Se o thread C não precisar desse bloqueio, a contenção futura entre os threads A e B pode ser evitada por algum tempo. (Claro, isso assume que há outros threads que podem ser executados. Não ajudará se a única maneira de o sistema como um todo fazer um progresso útil for executando threads que contenham.)
fonte
A partir daqui :
fonte
Acho que deve haver algum esclarecimento do OP sobre o contexto da pergunta - posso pensar em 2 respostas (embora tenha certeza de que há acréscimos a esta lista):
se você está se referindo ao "conceito" geral de contenção de encadeamentos e como ele pode se apresentar em um aplicativo, adio a resposta detalhada de @DavidSchwartz acima.
Há também o contador de desempenho '.NET CLR Locks and Threads: Total # of Contentions'. Conforme retirado da descrição do PerfMon para este contador, ele é definido como:
... e tenho certeza que outros para outros sistemas operacionais e estruturas de aplicativos.
fonte
Você tem 2 tópicos. Thread A e Thread B, você também tem o objeto C.
A está atualmente acessando o objeto C e colocou um bloqueio nesse objeto. B precisa acessar o objeto C, mas não pode fazer isso até que A libere o bloqueio no objeto C.
fonte
Outra palavra pode ser simultaneidade. É simplesmente a ideia de dois ou mais threads tentando usar o mesmo recurso.
fonte
Para mim, a contenção é uma competição entre 2 ou mais threads em um recurso compartilhado. O recurso pode ser uma fechadura, um contador, etc. Competição significa "quem o obtém primeiro". Quanto mais tópicos, mais contenção. Quanto mais frequente o acesso a um recurso, mais contenção.
fonte
Como no exemplo, os dois casos dão sentido de rivalidade.
fonte
A contenção de thread também é afetada por operações de E / S. Exemplo quando um Thread aguardando a leitura do arquivo pode ser considerado uma contenção. Use portas de conclusão de E / S como solução.
fonte
da documentação dotTrace
fonte