Tema: concurrency
-
Cancelamento e prazos em Go com context.Context
Propague um context.Context desde a requisição recebida por todas as chamadas que podem bloquear, derive contextos filhos com WithTimeout ou WithCancel, sempre chame a função cancel e verifique ctx.Done() em laços, para que a desconexão do cliente ou um prazo esgotado interrompa toda a árvore de goroutines em vez de deixá-las em execução.
-
Quando o asyncio ajuda e quando não ajuda
O asyncio executa muitas tarefas limitadas por I/O em uma única thread, suspendendo nos pontos de await; não acelera código limitado por CPU, e chamadas bloqueantes dentro de corrotinas travam o loop inteiro.
-
Níveis de isolamento de transação na prática
Read committed, repeatable read e serializable trocam concorrência por consistência; saber quais anomalias cada nível permite define quando adicionar locks explícitos ou tentativas repetidas (retries).
-
Como escolher entre threads, processos e asyncio para uma carga de trabalho em Python
Classifique primeiro o caminho crítico: espera por I/O combina com asyncio (muitas conexões, bibliotecas assíncronas) ou com um pool de threads (poucas chamadas bloqueantes); trabalho de CPU em Python puro exige processos ou um build free-threaded; código nativo que libera a GIL pode usar threads. Limite todos os pools, escolha explicitamente o método de início de processos e escreva o caminho de encerramento.
-
Verificar a leitura após a escrita usando as revisões retornadas
Confirme uma escrita por meio do identificador estável e da revisão, sem confundir uma atualização concorrente mais recente com o conteúdo exato que você enviou.
-
Trate tokens de escrita obsoletos como sinal para reler
Para se recuperar de uma pré-condição de escrita que falhou, releia o recurso e reconstrua a alteração pretendida sobre a versão atual.
-
Como impedir execuções simultâneas de um script administrativo: flock, lockf e mutex nomeado no Windows
Um script administrativo agendado ou disparado por um agente, que pode ser iniciado de novo antes de a execução anterior terminar, precisa de um lock e não de esperar que isso nunca aconteça. O flock(1) no Linux e o lockf(1) no FreeBSD associam um lock consultivo (advisory) do kernel a um processo em execução, por isso ele não fica obsoleto como um arquivo PID esquecido; no Windows, o equivalente é um System.Threading.Mutex nomeado.
-
A partir de que carga de trabalho o build free-threaded do CPython supera um pool de processos em um serviço com I/O e CPU misturados?
Pergunta em aberto: o build free-threaded elimina a GIL, mas acrescenta overhead em código single-thread e pode reativar a GIL ao importar uma extensão não preparada, enquanto pools de processos pagam por pickling e duplicação de memória. Para quais proporções entre CPU e espera, working sets e números de núcleos um pool de threads no build free-threaded entrega mais throughput por núcleo?
-
Armadilhas do async/await em C#: sync-over-async, async void e ConfigureAwait
Os erros clássicos em código assíncrono C# são bloquear uma Task com .Result, .Wait() ou GetAwaiter().GetResult() (deadlocks com um SynchronizationContext de thread única, esgotamento do thread pool em servidores), métodos async void cujas exceções não podem ser capturadas e o uso incorreto de ConfigureAwait(false), que pertence a bibliotecas de uso geral e não ao código de aplicação.
-
Threads virtuais em Java em linhas gerais: o que muda e o que não muda
A JEP 444 (JDK 21) introduz threads virtuais: threads baratas, escalonadas pelo JDK sobre um pequeno conjunto de threads de plataforma (carriers). As threads virtuais são desmontadas enquanto bloqueiam na maior parte da E/S do JDK, de modo que o código no estilo thread por requisição escala sem estilo assíncrono. Elas não são mais rápidas, nunca devem ser colocadas em pool e, até a JEP 491 (JDK 24), bloquear dentro de synchronized fixava o carrier.
-
Use leases com expiração em jobs distribuídos
Proteja um job reassumido contra um worker anterior atrasado, combinando verificações de propriedade com um fencing token monotonicamente crescente.
-
O GIL: o que ele serializa e o que ele não torna seguro
O global interpreter lock permite que apenas uma thread execute bytecode Python por vez e protege as estruturas internas do interpretador, não as invariantes do programa: sequências de leitura-modificação-escrita como counter += 1 ou verificar-e-definir em um dict continuam exigindo um threading.Lock. As builds free-threaded seguem a mesma regra.
-
Goroutines, channels e o pacote sync: visão geral da concorrência em Go
Uma instrução go executa uma chamada de função de forma concorrente, em uma pilha barata e expansível; os channels transportam valores entre goroutines e bloqueiam até que os dois lados estejam prontos; sync.WaitGroup, Mutex e Once cobrem os casos em que compartilhar memória é mais simples. Uma data race é um bug cujo resultado o modelo de memória restringe apenas em parte, e o detector -race é a ferramenta para encontrá-la.
-
Revalidar o estado após uma decisão do Jev e antes de um efeito colateral
Evita que uma decisão tomada sobre um estado anterior da aplicação seja aplicada às cegas depois de o registro, as permissões ou a política relevantes terem mudado.
-
Cobertura do detector de data races do Go: uma execução limpa não diz nada sobre caminhos não executados
Relacione os resultados de go test -race aos caminhos concorrentes realmente exercitados, incluindo a inicialização e o encerramento.
-
Erros de Send no Tokio: examine o estado mantido através do await
Corrija uma future criada com spawn examinando o que sobrevive à suspensão, em vez de adicionar implementações unsafe de traits.
-
Limitar a concorrência por host e por conta
Controle as chamadas simultâneas de ferramentas separadamente da taxa de requisições, usando filas limitadas e liberação de permissões segura em caso de cancelamento.
-
Triagem do ThreadSanitizer: recuperar o contrato de sincronização que falta
Leia os dois caminhos de acesso em conflito e corrija a regra de propriedade ou de sincronização que os liga.
Legível por máquina: JSON