4D v13.4Semaphore |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
4D v13.4
Semaphore
|
Semaphore ( semaforo {; ticCont} ) -> Resultado | ||||||||
Parámetro | Tipo | Descripción | ||||||
semaforo | Cadena |
![]() |
Semáforo a probar y colocar | |||||
ticCont | Entero largo |
![]() |
Máximo tiempo de espera | |||||
Resultado | Booleano |
![]() |
El semáforo se ha creado correctamente (FALSE) o El semáforo ya había sido creado (TRUE) | |||||
Un semáforo es una bandera compartida entre estaciones de trabajo (el ordenador de cada usuario) o entre procesos en la misma estación de trabajo. Un semáforo simplemente existe o no existe. Los métodos que cada usuario ejecuta pueden probar la existencia de un semáforo. Creando y probando semáforos, los métodos pueden comunicarse entre estaciones de trabajo.
La función Semaphore devuelve TRUE y no hace nada si el semaforo existe. Si semaforo no existe, Semaphore lo crea y devuelve FALSE. Sólo un usuario a la vez puede crear un semáforo. Si semaforo devuelve FALSE, esto significa que el semáforo no existe, pero también significa que el semáforo ha sido creado para el proceso en el cual la llamada se ha efectuado.
Semaphore devuelve FALSE si el semáforo no fue definido. También devuelve FALSE si el semáforo ya fue definido por el mismo proceso en el cual la llamada ha sido efectuada. semaforo está limitado a 255 caracteres, incluyendo prefijos (<>, $). Si pasa una cadena más larga, el semáforo se truncará.
El parámetro opcional ticCont le permite especificar un tiempo de espera (en tics) si semaforo ya está definido. En este caso, la función esperará o que el semáforo sea liberado o el tiempo de espera para terminar antes de devolver True.
Hay dos tipos de semáforos en 4D: semáforos locales y semáforos globales.
• Un semáforo local es visible para todos los procesos de una misma estación de trabajo y solamente en la estación de trabajo. Un semáforo local puede ser creado colocando al nombre del semáforo el signo dólar ($) como prefijo. Los semáforos locales se utilizan para monitorear operaciones entre los diferentes procesos ejecutados en la misma estación de trabajo. Por ejemplo, un semáforo local puede ser utilizado para monitorear el acceso a un array interproceso compartido por todos los procesos en una base mono usuario o en la estación de trabajo.
• Un semáforo global es visible para todos los usuarios y todos sus procesos. Los semáforos globales se utilizan para monitorear operaciones entre usuarios de una base multiusuario.
Los semáforos globales y locales son idénticos en su lógica. La diferencia reside en su alcance. En 4D Server, los semáforos globales se comparten entre todos los procesos ejecutados de todos los clientes. Un semáforo local sólo se comparte entre los procesos ejecutados en el equipo cliente donde ha sido creado.
En 4D , los semáforos globales y locales tienen el mismo alcance porque usted es el único usuario. Sin embargo, si su base está siendo utilizada en los dos entornos, asegúrese de utilizar semáforos globales y locales dependiendo de lo que quiera hacer.
Nota: los semáforos locales se recomiendan cuando el uso de un semáforo es necesario para manejar un aspecto local para un cliente de la aplicación, tal como la interfaz o un array de valores interproceso. El uso de un semáforo global provocará en este caso, no sólo intercambios de red innecesarios, sino también puede afectar otras máquinas cliente. El uso de un semáforo local evitará estos efectos indeseables.
Los semáforos no se utilizan para proteger el acceso a los registros. Esta gestión la realiza automáticamente 4D y 4D Server. Utilice semáforos para evitar que varios usuarios realicen la misma operación al mismo tiempo.
En este ejemplo, usted quiere evitar que dos usuarios efectúen simultáneamente una actualización global de los precios en una tabla Productos. El siguiente método utiliza semáforos para hacer esto:
If(Semaphore("ActualizacionPrecios")) ` Trate de crear el semáforo
ALERT("Otro usuario ya está actualizando los precios. Inténtelo más tarde.")
Else
ActualizarPrecios ` Actualización de todos los precios
CLEAR SEMAPHORE("ActualizacionPrecios") ` Borrar el semáforo
End if
El siguiente ejemplo utiliza un semáforo local. En una base con varios procesos, usted quiere mantener una lista de "Cosas por hacer". Usted quiere mantener la lista en un array interproceso y no en una tabla. Usted utiliza un semáforo para evitar el acceso simultáneo. En esta situación, sólo necesita utilizar un semáforo local, porque su lista "Cosas por hacer" es sólo para su uso personal.
El array interproceso se inicializa en el método Startup:
ARRAY TEXT(◊ListaHacer;0) ` La lista de cosas por hacer está inicialmente vacía
Este es el método utilizado para añadir elementos a la lista de cosas por hacer:
` Método de proyecto AGREGAR A LISTA DE COSAS POR HACER
` AGREGAR A LISTA DE COSAS POR HACER ( Texto )
` AGREGAR A LISTA DE COSAS POR HACER ( Elemento de la lista de cosas por hacer)
C_TEXT($1)
If(Not(Semaphore("$AccesoLista";300)))
` Espera 5 segundos si el semáforo ya existe
$vlElem:=Size of array(◊ListaHacer)+1
INSERT IN ARRAY(◊ListaHacer;$vlElem)
◊ListaHacer{$vlElem}:=$1
CLEAR SEMAPHORE("$AccesoLista") ` Borrar el semáforo
End if
Puede llamar este método desde cualquier proceso.
Este método permite no ejecutar un método si el semáforo está presente; el método informa el método de llamada con un código de error y un texto plano.
Sintaxis:
$L_Error:=Semaphore_proof(->$T_Text_error)
// Estructura de protección por semáforo
C_LONGINT($0)
C_POINTER($1) // mensaje de error
// Inicio del 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ábamos 300 tics pero el semáforo
// no fue lanzado por el que lo ubicó:
// terminamos aquí
$L_MyError:=-1
Else
// Este método solo se ejecuta por un proceso a la vez
// Ubicamos el semáforo al mismo tiempo que lo introducimos
// así que somos los únicos que lo podemos eliminar
// Hacer algo
...
// Terminar eliminando el semáforo
CLEAR SEMAPHORE($T_Sema_local)
End if
C_TEXT($T_Message)
If($L_MyError=-1)
$T_Message:="El semáforo "+$T_Sema_local+" tiene el acceso bloqueado al resto del código"
Else
$T_Message:="OK"
End if
$0:=$L_MyError
$1->:=$T_Message // El método llamante recibe un código de error y una explicación en texto plano
Producto: 4D
Tema: Procesos (Comunicación)
Número
143
Lista alfabética de los comandos
Modificado: 4D v11 SQL
CLEAR SEMAPHORE
Test semaphore