Signal
Las señales son herramientas que ofrece el lenguaje 4D para gestionar las interacciones y evitar conflictos entre procesos en una aplicación multiproceso. Las señales le permiten asegurarse de que uno o más procesos esperarán a que se complete una tarea específica antes de continuar la ejecución. Todo proceso puede esperar y/o liberar una señal.
Los semáforos también pueden utilizarse para gestionar las interacciones. Los semáforos permiten asegurarse de que dos o más procesos no modifican el mismo recurso (archivo, registro...) al mismo tiempo. Sólo el proceso que define el semáforo puede eliminarlo.
Objeto signal
Una señal es un objeto compartido que debe ser pasado como parámetro a los comandos que llaman o crean trabajadores o procesos.
Un objeto 4D.Signal
contiene los siguientes métodos y propiedades integrados:
Todo worker/proceso que llame al método .wait()
suspenderá su ejecución hasta que la propiedad .signaled
sea verdadera. Mientras espera una señal, el proceso que llama no utiliza ninguna CPU. Esto puede ser muy interesante para el rendimiento en aplicaciones multiproceso. La propiedad .signaled
se convierte en true cuando cualquier worker/proceso llama al método .trigger()
.
Tenga en cuenta que para evitar situaciones de bloqueo, el .wait()
también puede regresar después de que se haya alcanzado un tiempo de espera definido.
Los objetos signal se crean con el comando New signal.
Trabajar con señales
En 4D, se crea un nuevo objeto signal llamando al comando New signal
. Una vez creada, esta señal debe pasarse como parámetro a los comandos New process
o CALL WORKER
para que la modifiquen cuando hayan terminado la tarea que quiere esperar.
signal.wait()
debe ser llamado desde el worker/proceso que necesita que otro worker/proceso termine una tarea para poder continuar.signal.trigger()
debe llamarse desde el worker/proceso que terminó su ejecución para liberar a todos los demás.
Una vez que una señal ha sido liberada utilizando una llamada signal.trigger()
, no puede ser reutilizada de nuevo. Si desea definir otra señal, debe llamar de nuevo al comando New signal
.
Dado que un objeto signal es un objeto compartido, puede utilizarlo para devolver resultados de los workers/procesos llamados, siempre que no olvide escribir los valores dentro de una estructura Use...End use
(ver ejemplo).
Ejemplo
var $signal : 4D.Signal
// Creación de un signal
$signal:=New signal
// llamar al proceso principal y ejecutar el método OpenForm
CALL WORKER(1;"OpenForm";$signal)
// hacer otro cálculo
...
// Esperando el final del proceso
$signaled:=$signal.wait()
// Procesamiento de los resultados
$calc:=$signal.result+...
Método OpenForm:
#DECLARE ($signal : 4D.Signal)
var $form : Object
$form:=New object("value";0)
// Abrir el formulario
$win:=Open form window("Information";Movable form dialog box)
DIALOG("Information";$form)
CLOSE WINDOW($win)
// Añade un nuevo atributo a su objeto compartido $signal para pasar su resultado al otro proceso:
Use($signal)
$signal.result:=$form.value
End use
// Activar la señal al proceso de espera
$signal.trigger()
Resumen
.description : Text contiene una descripción personalizada para el objeto Signal . |
.signaled: Boolean contiene el estado actual del objeto Signal |
.trigger( ) establece la propiedad signaled del objeto signal como true |
.wait( { timeout : Real } ) : Boolean hace que el proceso actual espere hasta que la propiedad .signaled del objeto signal se convierta en true o que el timeout terminé |
New signal
Histórico
Lanzamiento | Modificaciones |
---|---|
17 R4 | Añadidos |
New signal { ( description : Text ) } : 4D.Signal
Parámetros | Tipo | Descripción | |
---|---|---|---|
description | Text | -> | Descripción para la señal |
Result | 4D.Signal | <- | Objeto nativo que encapsula la señal |
|
Descripción
El comando New signal
crea un objeto 4D.Signal
.
Una señal es un objeto compartido que puede ser pasado como parámetro de un worker o proceso a otro worker o proceso, de manera que:
- el worker/proceso llamado puede actualizar el objeto de la señal después de que se haya completado el procesamiento específico
- el worker/proceso que llama puede detener su ejecución y esperar hasta que se actualice la señal, sin consumir recursos de la CPU.
Opcionalmente, en el parámetro description puede pasar un texto personalizado que describa la señal. Este texto también puede definirse después de la creación de la señal.
Dado que el objeto señal es un objeto compartido, también se puede utilizar para mantener las propiedades del usuario, incluyendo la propiedad .description
, llamando a la estructura Use...End use
.
Valor devuelto
Un nuevo objeto 4D.Signal
.
Ejemplo
Este es un ejemplo típico de un worker que fija una señal:
var $signal : 4D.Signal
$signal:=New signal("This is my first signal")
CALL WORKER("myworker";"doSomething";$signal)
$signaled:=$signal.wait(1) //espera 1 segundo como máximo
If($signaled)
ALERT("myworker finished the work. Result: "+$signal.myresult)
Else
ALERT("myworker no ha terminado en menos de 1s")
End if
El método doSomething puede ser:
#DECLARE ($signal : 4D.Signal)
//todo proceso
//...
Use($signal)
$signal.myresult:=$processingResult //devolver el resultado
End use
$signal.trigger() //La operación se ha terminado
.description
Histórico
Lanzamiento | Modificaciones |
---|---|
17 R4 | Añadidos |
.description : Text
Descripción
La propiedad .description
contiene una descripción personalizada para el objeto Signal
..
.description
puede definirse al crear el objeto signal o en cualquier momento. Tenga en cuenta que, dado que el objeto Signal
es un objeto compartido, cualquier acceso en modo de escritura a la propiedad .description
debe estar rodeado por una estructura Use...End use
.
Esta propiedad es lectura-escritura.
.signaled
Histórico
Lanzamiento | Modificaciones |
---|---|
17 R4 | Añadidos |
.signaled: Boolean
Descripción
La propiedad .signaled
contiene el estado actual del objeto Signal
. . When the signal is created, .signaled
is False.
Esta propiedad es de sólo lectura.
.trigger()
Histórico
Lanzamiento | Modificaciones |
---|---|
17 R4 | Añadidos |
.trigger( )
| Parámetros | Tipo | | Descripción | | ---------- | ---- |::| ------------------------------------------------------- | | | | | No requiere ningún parámetro|
|
Descripción
La función .trigger( )
establece la propiedad signaled
del objeto signal como true y despierta a todos los workers o procesos que esperan esta señal.
Si la señal ya está en el estado de señalización (es decir, la propiedad signaled
ya es true), la función no hace nada.
.wait()
Histórico
Lanzamiento | Modificaciones |
---|---|
17 R4 | Añadidos |
.wait( { timeout : Real } ) : Boolean
Parámetros | Tipo | Descripción | |
---|---|---|---|
timeout | Real | -> | Tiempo máximo de espera de la señal en segundos |
Result | Boolean | <- | Estado de la propiedad .signaled |
|
Descripción
La función .wait( )
hace que el proceso actual espere hasta que la propiedad .signaled
del objeto signal se convierta en true o que el timeout terminé.
Para evitar que el código se bloquee, puede pasar un tiempo máximo de espera en segundos en el parámetro timeout (se aceptan decimales).
Atención: la llamada a
.wait( )
sin un timeout en el proceso principal de 4D no es recomendable porque podría congelar toda la aplicación 4D.
Si signal ya está en el estado de señalización (es decir, la propiedad .signaled
ya es true), la función devuelve inmediatamente, sin esperar.
La función devuelve el valor de la propiedad .signaled
. La evaluación de este valor permite saber si la función devuelta porque el .trigger( )
se ha llamado (.signaled
es true) o si el timeout vencido (.signaled
es false).
El estado de un proceso que espera un signal es
Waiting for internal flag
.