<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Artur Freire</title>
    <description>The latest articles on DEV Community by Artur Freire (@freirart).</description>
    <link>https://dev.to/freirart</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3856397%2F900421f6-53fd-45e5-8ad3-7401a4bcc2c2.png</url>
      <title>DEV Community: Artur Freire</title>
      <link>https://dev.to/freirart</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/freirart"/>
    <language>en</language>
    <item>
      <title>Threads, processos, deadlock e race condition no contexto de concorrência e paralelismo</title>
      <dc:creator>Artur Freire</dc:creator>
      <pubDate>Mon, 06 Apr 2026 10:30:00 +0000</pubDate>
      <link>https://dev.to/freirart/threads-processos-deadlock-e-race-condition-no-contexto-de-concorrencia-e-paralelismo-6o0</link>
      <guid>https://dev.to/freirart/threads-processos-deadlock-e-race-condition-no-contexto-de-concorrencia-e-paralelismo-6o0</guid>
      <description>&lt;p&gt;Navegando pelas redes sociais, você muito provavelmente já se deparou com aqueles &lt;em&gt;quizzes&lt;/em&gt; “10 perguntas que todo formando em computação deveria saber responder”. Uma das perguntas que eu mais vejo aparecer nesses questionários é: &lt;strong&gt;qual é a diferença entre uma &lt;em&gt;thread&lt;/em&gt; e um processo?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Você teria essa resposta na ponta da língua? Eu achava que sim até aprofundar minha leitura no assunto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3jf0qw2fc5w9027ludyr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3jf0qw2fc5w9027ludyr.png" alt="Figura 1 — Analogia comumente utilizada para responder à pergunta sobre threads e processos." width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Imaginando uma bebida, o processo seria o líquido e a &lt;em&gt;thread&lt;/em&gt; seria o canudo”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Esta é a analogia que mais fazem ao tentar responder à pergunta. No entanto, &lt;strong&gt;eu não acredito que ela relaciona os termos de forma adequada&lt;/strong&gt;. Isto porque a hierarquia dos termos na analogia está invertida: não são as &lt;em&gt;threads&lt;/em&gt; que “contêm os processos”, mas o processo é quem contém as &lt;em&gt;threads&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Uma analogia mais apropriada seria a de que o processo é a fábrica, com seus maquinários e certificações de segurança, enquanto a &lt;em&gt;thread&lt;/em&gt; seria o operador, a unidade de execução que desempenha suas funções em cima dos recursos que a fábrica reservou.&lt;/p&gt;

&lt;p&gt;Imagine que estamos desenvolvendo um sistema para uma padaria de bairro com uma média de &lt;strong&gt;50 vendas por dia&lt;/strong&gt;. As vendas são registradas num &lt;a href="https://www.ledger.com/pt-br/academy/glossary/ledger#:~:text=Um%20livro%2Draz%C3%A3o%20%C3%A9%20um%20registro%20digital%20ou%20f%C3%ADsico%20que%20registra%20as%20transa%C3%A7%C3%B5es%20associadas%20a%20um%20sistema%20financeiro" rel="noopener noreferrer"&gt;&lt;em&gt;ledger book&lt;/em&gt;&lt;/a&gt; de modo que, diariamente, é gerado um relatório com o saldo do caixa e o estoque atualizados. Por conta do baixo volume, &lt;strong&gt;a decisão de processar sequencialmente cada registro é ótima&lt;/strong&gt; pois adequa a complexidade da solução ao tamanho da demanda, sendo possível obter o fechamento do dia em milissegundos.&lt;/p&gt;

&lt;p&gt;Agora imagine que essa padaria cresceu e se tornou uma rede nacional com média de &lt;strong&gt;1 milhão de vendas por dia&lt;/strong&gt;. O processamento de um volume tão grande poderia levar horas se realizado por uma única &lt;em&gt;thread&lt;/em&gt;. Neste caso, &lt;strong&gt;torna-se necessária a divisão do processamento em múltiplas &lt;em&gt;threads&lt;/em&gt;&lt;/strong&gt;, efetivamente implementando estratégias de concorrência e paralelismo que, embora muitas vezes sejam utilizadas como sinônimos, não são.&lt;/p&gt;

&lt;p&gt;Além de otimizar o tempo ocioso nos ambientes &lt;em&gt;single thread&lt;/em&gt; ao alternar entre tarefas (como se pode observar no &lt;a href="https://nodejs.org/en/learn/asynchronous-work/event-loop-timers-and-nexttick" rel="noopener noreferrer"&gt;&lt;em&gt;Event Loop&lt;/em&gt;&lt;/a&gt; do Node.js), as estratégias de concorrência são fundamentais para a &lt;strong&gt;manutenção da consistência&lt;/strong&gt; numa solução com paralelismo. Isto porque o ambiente &lt;em&gt;multi-thread&lt;/em&gt; introduz &lt;strong&gt;complexidades inerentes à solução&lt;/strong&gt; tais como o &lt;em&gt;race condition&lt;/em&gt; e o &lt;em&gt;deadlock&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Ao trabalhar com uma única &lt;em&gt;thread&lt;/em&gt;, a consistência é garantida por definição pois o processamento é realizado de forma sequencial de modo que “&lt;strong&gt;uma única mão mexe nos dados&lt;/strong&gt;”. No paralelismo, com os acessos simultâneos à memória compartilhada, surge a necessidade de responder às perguntas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;O que fazer quando &lt;em&gt;threads&lt;/em&gt; distintas concorrem pelo mesmo recurso ao mesmo tempo? (&lt;em&gt;race condition&lt;/em&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;O que acontece quando uma &lt;em&gt;thread&lt;/em&gt; precisa de um recurso que está bloqueado por outra?&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A manutenção da consistência neste cenário representa um dos maiores desafios da computação moderna conforme argumenta o professor Edward A. Lee (UC Berkeley) em seu &lt;em&gt;paper The Problems with Threads&lt;/em&gt; (2006):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;[Parallelism] discards the most essential and appealing properties of sequential computation: understandability, predictability, and determinism.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Inclusive, uma solução inadequada para responder à segunda pergunta pode levar ao problema de &lt;em&gt;deadlock&lt;/em&gt; onde duas ou mais &lt;em&gt;threads&lt;/em&gt; ficam esperando indefinidamente por recursos que a outra possui:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fftkckiy5pntximvawysp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fftkckiy5pntximvawysp.png" alt="Figura 2 — Diagrama para representação de um deadlock." width="733" height="551"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O deadlock só ocorre quando a estratégia de concorrência implementada apresenta as seguintes características:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;exclusão mútua&lt;/strong&gt; (um acesso por vez por meio de &lt;em&gt;locks&lt;/em&gt;, &lt;em&gt;mutexes&lt;/em&gt; ou semáforos);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;hold-and-wait&lt;/em&gt;&lt;/strong&gt; (a &lt;em&gt;thread&lt;/em&gt; não libera o recurso reservado enquanto está esperando por outro);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;não preempção&lt;/strong&gt; (um recurso reservado para uma &lt;em&gt;thread&lt;/em&gt; não pode ser “tomado” por outra);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;espera circular&lt;/strong&gt; (conforme abordado no parágrafo e imagem anteriores).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Apesar disso, no exemplo da padaria a probabilidade de acontecer um &lt;em&gt;deadlock&lt;/em&gt; é &lt;strong&gt;praticamente inexistente&lt;/strong&gt;. Isto porque trata-se de um problema do tipo &lt;em&gt;Single Instruction, Multiple Data&lt;/em&gt; (SIMD) onde a mesma operação é aplicada sobre um conjunto de dados com &lt;em&gt;Data Partitioning&lt;/em&gt; (cada &lt;em&gt;thread&lt;/em&gt; cuida de uma faixa específica do dado). Quando não há compartilhamento de estado e o acesso aos dados acontece de maneira &lt;strong&gt;uniforme e independente&lt;/strong&gt; por cada &lt;em&gt;thread&lt;/em&gt;, o uso de &lt;em&gt;locks&lt;/em&gt; tende a ser dispensável.&lt;/p&gt;

&lt;p&gt;A computação paralela é um campo extenso que vem sendo estudado há décadas. Os tópicos vão desde a natureza do problema que está sendo resolvido (única instrução para múltiplos dados, múltiplas instruções para um único dado, etc.) até a escolha do modelo de distribuição e processamento das tarefas (&lt;em&gt;task graph&lt;/em&gt;, &lt;em&gt;master-slave&lt;/em&gt;, etc.), além de questões como o problema de &lt;em&gt;Context Switching&lt;/em&gt; e os limites físicos do paralelismo.&lt;/p&gt;

&lt;p&gt;Em suma, este artigo buscou mostrar como o &lt;em&gt;hardware&lt;/em&gt; moderno é utilizado para a execução de tarefas simultâneas e a complexidade que isto traz. &lt;strong&gt;Mas e numa aplicação de banco de dados, por exemplo?&lt;/strong&gt; Como os conceitos de paralelismo e concorrência são implementados? &lt;strong&gt;Isso é assunto para um próximo artigo.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>parallelism</category>
      <category>threads</category>
      <category>deadlock</category>
      <category>concurrency</category>
    </item>
  </channel>
</rss>
