Pular para o conteúdo

Uma variável por thread

Inicialização declarada por thread e finalizador quando ela acaba — o que o armazém sozinho não dá.

Um armazém por thread resolve metade do problema. A outra metade é o que costuma faltar: a inicialização declarada num lugar só, e o finalizador quando a thread acaba.

Sem finalizador, uma conexão aberta por thread fica aberta depois que ela morre — e o sintoma aparece no servidor, não no código.

dataforge
adopt Arcane.Inicio as I

// a inicializacao roda UMA VEZ POR THREAD, e cada uma ve a sua
contador := I.local(lambda => {"n": 0})

caixa := I.meu(contador)
caixa["n"] := caixa["n"] + 1

assert I.meu(contador)["n"] is 1
assert I.threads_com_valor(contador) bigger_eq 1
SímboloO que faz
I.local(inicial, ao_terminar?)cria a variável; inicial é uma ação que constrói o valor
I.meu(local)o valor desta thread, criando-o na primeira vez
I.definir(local, v)troca o valor desta thread
I.limpar(local)esquece; o próximo meu nasce de novo
I.threads_com_valor(local)quantas threads têm valor guardado

Três decisões#

`inicial` é uma ação, e não um valor. Um valor seria compartilhado por todas as threads — que é exatamente o que a variável por thread existe para evitar. Passar um valor é recusado, com esse motivo na mensagem.

A inicialização roda fora da trava. Ela é código de quem chamou, pode demorar, e segurar a trava ali faria uma thread lenta parar todas as outras.