Controles de Threading
A aba Threading fornece 8 controles para programacao concorrente: threads, primitivas de sincronizacao, pools de threads e canais de comunicacao inter-threads. Todos os controles sao multiplataforma e usam mecanismos nativos de threading do SO.
TThread CT_THREAD = 63
Executa codigo em uma thread separada do SO. O principal bloco de construcao para operacoes concorrentes.
| Propriedade | Tipo | Padrao | Descricao |
nPriority | Numerico | 0 | Prioridade da thread (-2 mais baixa a +2 mais alta) |
lFreeOnTerminate | Logico | .F. | Destruir objeto automaticamente quando a thread termina |
lRunning | Logico | .F. | Thread esta executando atualmente (somente leitura) |
lFinished | Logico | .F. | Thread foi concluida (somente leitura) |
nThreadId | Numerico | 0 | Identificador da thread no SO (somente leitura) |
| Evento | Categoria | Descricao |
OnExecute | Ciclo de vida | Codigo para executar na thread (obrigatorio) |
OnTerminate | Ciclo de vida | Thread concluiu execucao (chamado na thread principal) |
| Metodo | Descricao |
Start() | Iniciar execucao da thread |
Wait( nTimeout ) | Aguardar thread terminar. Tempo limite opcional em ms |
Cancel() | Solicitar cancelamento cooperativo |
| Plataforma | Implementacao Nativa |
| Windows | CreateThread / _beginthreadex |
| macOS | pthread_create |
| Linux | pthread_create |
TMutex CT_MUTEX = 64
Bloqueio de exclusao mutua. Garante que apenas uma thread acesse um recurso compartilhado por vez.
| Metodo | Descricao |
Lock() | Adquirir o mutex. Bloqueia se ja estiver bloqueado por outra thread |
Unlock() | Liberar o mutex |
TryLock() | Tentar adquirir sem bloquear. Retorna .T. se adquiriu |
| Plataforma | Implementacao Nativa |
| Windows | CRITICAL_SECTION |
| macOS | pthread_mutex_t |
| Linux | pthread_mutex_t |
TSemaphore CT_SEMAPHORE = 65
Semaforo de contagem. Controla o acesso a um pool de recursos compartilhados com contagem limitada.
| Propriedade | Tipo | Padrao | Descricao |
nInitialCount | Numerico | 0 | Contagem inicial do semaforo |
nMaxCount | Numerico | 1 | Contagem maxima do semaforo |
| Metodo | Descricao |
Wait( nTimeout ) | Decrementar contagem. Bloqueia se contagem e zero. Tempo limite opcional em ms |
Signal() | Incrementar contagem. Acorda uma thread esperando |
TCriticalSection CT_CRITICALSECTION = 66
Primitiva de sincronizacao leve. Mais rapida que TMutex para proteger trechos curtos de codigo dentro do mesmo processo.
| Metodo | Descricao |
Enter() | Entrar na secao critica. Bloqueia se outra thread estiver dentro |
Leave() | Sair da secao critica |
TryEnter() | Tentar entrar sem bloquear. Retorna .T. se entrou |
TThreadPool CT_THREADPOOL = 67
Gerencia um pool de threads de trabalho reutilizaveis. Envie tarefas ao pool em vez de criar threads individuais.
| Propriedade | Tipo | Padrao | Descricao |
nMinThreads | Numerico | 2 | Numero minimo de threads de trabalho |
nMaxThreads | Numerico | 8 | Numero maximo de threads de trabalho |
nQueueSize | Numerico | 256 | Tamanho maximo da fila de tarefas pendentes |
nActiveThreads | Numerico | 0 | Threads de trabalho ativas atualmente (somente leitura) |
nPendingTasks | Numerico | 0 | Tarefas aguardando na fila (somente leitura) |
| Evento | Categoria | Descricao |
OnTaskComplete | Ciclo de vida | Uma tarefa concluiu execucao. Parametros: xResult, nTaskId |
OnError | Erro | Uma tarefa gerou um erro. Parametros: oError, nTaskId |
| Metodo | Descricao |
Submit( bTask ) | Adicionar uma tarefa (bloco de codigo) a fila. Retorna nTaskId |
WaitAll( nTimeout ) | Aguardar todas as tarefas pendentes concluirem |
Shutdown() | Parar todas as threads apos concluir tarefas pendentes |
TAtomicInt CT_ATOMICINT = 68
Inteiro atomico sem bloqueio. Fornece operacoes de contador thread-safe sem bloqueio explicito.
| Metodo | Descricao |
Inc() | Incrementar atomicamente em 1. Retorna novo valor |
Dec() | Decrementar atomicamente em 1. Retorna novo valor |
Get() | Ler valor atual |
Set( nValue ) | Definir atomicamente como nValue |
CompareExchange( nExpected, nNew ) | Se atual == nExpected, definir como nNew. Retorna .T. se trocou |
Add( nValue ) | Somar atomicamente nValue. Retorna novo valor |
| Plataforma | Implementacao Nativa |
| Windows | InterlockedIncrement / InterlockedCompareExchange |
| macOS | __atomic builtins (GCC/Clang) |
| Linux | __atomic builtins (GCC/Clang) |
TCondVar CT_CONDVAR = 69
Variavel de condicao. Permite que threads aguardem ate que uma condicao especifica seja sinalizada por outra thread.
| Metodo | Descricao |
Wait( oMutex, nTimeout ) | Liberar mutex e aguardar sinal. Re-adquire mutex ao acordar. Tempo limite opcional em ms |
Signal() | Acordar uma thread aguardando |
Broadcast() | Acordar todas as threads aguardando |
| Plataforma | Implementacao Nativa |
| Windows | CONDITION_VARIABLE |
| macOS | pthread_cond_t |
| Linux | pthread_cond_t |
TChannel CT_CHANNEL = 70
Canal de mensagens thread-safe para comunicacao inter-threads. Inspirado nos canais do Go e concorrencia CSP.
| Propriedade | Tipo | Padrao | Descricao |
nBufferSize | Numerico | 0 | Capacidade do buffer (0 = sem buffer/sincrono) |
lClosed | Logico | .F. | Canal foi fechado (somente leitura) |
| Metodo | Descricao |
Send( xValue ) | Enviar um valor ao canal. Bloqueia se buffer estiver cheio |
Receive() | Receber um valor do canal. Bloqueia se vazio |
TryReceive( @xValue ) | Recebimento sem bloqueio. Retorna .T. se um valor estava disponivel |
Close() | Fechar o canal. Nenhum valor pode mais ser enviado |
| Evento | Categoria | Descricao |
OnReceive | Dados | Valor recebido (alternativa a sondagem). Parametros: xValue |
Exemplo de Codigo: Padrao Produtor-Consumidor
// Padrao produtor-consumidor usando TChannel e TThread
FUNCTION Main()
LOCAL oChannel, oProducer, oConsumer
// Criar um canal com buffer de capacidade 10
oChannel := TChannel():New()
oChannel:nBufferSize := 10
// Thread produtora: gera itens de trabalho
oProducer := TThread():New()
oProducer:lFreeOnTerminate := .T.
oProducer:OnExecute := { || ProduzirItens( oChannel ) }
// Thread consumidora: processa itens de trabalho
oConsumer := TThread():New()
oConsumer:lFreeOnTerminate := .T.
oConsumer:OnExecute := { || ConsumirItens( oChannel ) }
// Iniciar ambas as threads
oProducer:Start()
oConsumer:Start()
// Aguardar produtor terminar, entao fechar canal
oProducer:Wait()
oChannel:Close()
// Aguardar consumidora drenar itens restantes
oConsumer:Wait()
QOut( "Tudo concluido!" )
RETURN NIL
FUNCTION ProduzirItens( oChannel )
LOCAL n
FOR n := 1 TO 100
oChannel:Send( "Tarefa #" + Str( n ) )
QOut( "Produzido: Tarefa #" + Str( n ) )
NEXT
RETURN NIL
FUNCTION ConsumirItens( oChannel )
LOCAL xItem
DO WHILE ! oChannel:lClosed .OR. oChannel:TryReceive( @xItem )
xItem := oChannel:Receive()
IF xItem != NIL
QOut( "Consumido: " + xItem )
ENDIF
ENDDO
RETURN NIL
8 Controles de Threading
Todas as primitivas de threading mapeiam diretamente para mecanismos nativos do SO para maximo desempenho.
Use TChannel para comunicacao segura entre threads em vez de variaveis compartilhadas com bloqueios.