4D v16.3Semaphore |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
4D v16.3
Semaphore
|
Semaphore ( semaforo {; tickCount} ) -> Resultado | ||||||||
Parâmetro | Tipo | Descrição | ||||||
semaforo | String |
![]() |
Semáforo a testar e estabelecer | |||||
tickCount | Inteiro longo |
![]() |
Máximo tempo de espera | |||||
Resultado | Booleano |
![]() |
O semáforo foi criado corretamente (FALSE) ou O semáforo já tinha sido criado (TRUE) | |||||
Um semáforo é uma bandeira compartihada entre estações de trabalho (o computador de cada usuário) ou entre processos na mesma estação de trabalho. Um semáforo simplesmente existe ou não existe. Os métodos que cada usuário executa podem provar a existência de um semáforo. Criando e provando semáforos, os métodos podem ser comunicados entre estações de trabalho.
A função Semaphore devolve TRUE e não faz nada se o semaforo existe. Se não existe o semáforo, Semaphore o cria e devolve FALSE. Só um usuário ao tempo pode criar um semáforo. Se semaforo devolve FALSE, isto significa que o semáforo não existe, mas também significa que o semáforo foi criado para o processo no qual a chamada for realizada.
Semaphore devolve FALSE se o semáforo não foi definido. Também devolve FALSE se o semáforo já foi definido pelo mesmo processo no qual a chamada tenha sido realizada. Um semáforo está limitado a 255 caracteres, incluindo prefixos (<>, $). Se passa uma cadeia mais longa, o semáforo será provado com a cadeia truncada.
Lembre que os nomes dos semáforos são sensíveis as maiúsculas e minúsculas em 4D (por exemplo, o programa considera que "MySemaphore" é diferente de "mysemaphore"
O parâmetro opcional tickCount lhe permite especificar um tempo de espera (em ticks) se semaforo já está definido. Neste caso, a função esperará o que o semáforo seja liberado ou o tempo de espera para terminar antes de devolver True.
Há dois tipos de semáforos em 4D: semáforos locais e semáforos globais.
Abaixo um código típico para usar um semáforo:
While(Semaphore("MySemaphore";300))
IDLE
End while
// coloque o código protegido por semáforo aqui
CLEAR SEMAPHORE("MySemaphore")
Neste exemplo, você quer evitar que dois usuários realizem simultâneamente uma atualização global dos preços em uma tabela Produtos. O seguinte método utiliza semáforos para fazer isto:
If(Semaphore("AtualizacaoPreços")) ` tente criar o semáforo
ALERT("Outro usuário já está atualizando os preços. Tente mais tarde.")
Else
AtualizarPreços ` Atualização de todos os preços
CLEAR SEMAPHORE("AtualizaçãoPreços") ` Apagar o semáforo
End if
O exemplo a seguir utiliza um semáforo local. Em um banco de dados com vários processos, você pode querer manter uma lista de "Coisas a fazer". Você deseja manter a lista em um array interprocesso e não em uma tabela. Você utiliza um semáforo para evitar o acesso simultâneo. Nesta situação, só necessita utilizar um semáforo local, porque sua lista "Coisas a fazer" serve apenas para seu uso pessoal.
O array interprocesso se inicializa no método Startup:
ARRAY TEXT(◊ListaFazer;0) ` A lista de coisas a fazer está inicialmente vazia
Este é o método utilizado para adicionar elementos à lista de coisas por fazer:
` Método de projeto AGREGAR A LISTA DE COISAS A FAZER
` AGREGAR A LISTA DE COISAS A FAZER ( Texto )
` AGREGAR A LISTA DE COISAS A FAZER ( Elemento da lista de coisas a fazer)
C_TEXT($1)
If(Not(Semaphore("$AcessoLista";300)))
` Espera 5 segundos se o semáforo já existe
$vlElem:=Size of array(◊ListaFazer)+1
INSERT IN ARRAY(◊ListaFazer;$vlElem)
◊ListaFazer{$vlElem}:=$1
CLEAR SEMAPHORE("$AcessoLista") ` Apagar o semáforo
End if
Pode chamar este método desde qualquer processo.
CloseEste método permite não executar um método se o semáforo está presente; o método informa o método de chamada com um código de erro e um texto plano.
Sintaxe:
$L_Error:=Semaphore_proof(->$T_Text_error)
// Estrutura de proteção por semáforo
C_LONGINT($0)
C_POINTER($1) // mensagem de erro
// Inicio do método
C_LONGINT($L_MyError)
$L_MyError:=1
C_TEXT($T_Sema_local)
$T_Sema_local:="$tictac"
If(Semaphore($T_Sema_local;300))
// Esperávamos 300 tics mas o semáforo
// não foi lançado pelo que o localizou:
// terminamos aqui
$L_MyError:=-1
Else
// Este método somente executa por um processo de cada vez
// Localizamos o semáforo ao mesmo tempo que o introduzimos
// assim que somos os únicos que o podemos excluir
// Fazer algo
...
// Terminar excluindo o semáforo
CLEAR SEMAPHORE($T_Sema_local)
End if
C_TEXT($T_Message)
If($L_MyError=-1)
$T_Message:="O semáforo "+$T_Sema_local+" tem o acesso bloqueado ao resto do código"
Else
$T_Message:="OK"
End if
$0:=$L_MyError
$1->:=$T_Message // O método chamado recebe um código de erro e uma explicação em texto plano
Produto: 4D
Tema: Processos (Comunicações)
Número
143
Modificado: 4D v11 SQL
Manual de linguagem 4D ( 4D v16)
Manual de linguagem 4D ( 4D v16.1)
Manual de linguagem 4D ( 4D v16.2)
Manual de linguagem 4D ( 4D v16.3)