A continuación encontrarás traducido al castellano el artículo escrito por William Yu y publicado originalmente en el Blog oficial de Xojo.
En Xojo 2024r3.1 introdujimos la muy solicitada característica de hilos preemptivos. Este nuevo tipo de hilo permite la ejecución realmente independiente de código, separado del hilo principal o de cualquier otro hilo; lo que significa la capacidad de utilizar todos los núcleos de la CPU. Exploremos algunas de las mejoras realizadas desde que se introdujo dicha capacidad.
Protegiendo nuestros Objetos
Los objetos de Xojo se crean de forma única e implementan un contador de referencias (es decir, otros objetos que mantienen una referencia sobre el mismo), siendo este un detalle del cual no tienen por qué ser conscientes la mayoría. Sin embargo, y cuando se trabaja con hilos preemptivos, los objetos requieren de forma inherente de una protección especial.
En Xojo 2024r3.1 implementamos salvaguardas para permitir el uso de los objetos en hilos preemptivos, pero dicho enfoque no fue tan eficiente como podría ser. Algunas operaciones, como el paso de los objetos como parámetros o su asignación a propiedades incurrían en un sobrecoste, y dichos costes acababan sumándose.
De igual modo que nuestros objetos se construyen de forma única, también requieren de un enfoque único en cuanto a su protección. En Xojo 2024r4 hemos actualizado la forma en la que protegemos a nuestros objetos, de modo que esta operación se realiza mucho más rápida, y acelerando por tanto la experiencia general cuando se ejecutan los hilos preemptivos.
Como ejemplo de este aumento en la eficacia, comprueba esta entrada del foro con los resultados obtenidos por los usuarios en las pruebas del “One Billion Row Challenge“.
Destrucción de Objetos
Como se ha mencionado, nuestros objetos se construyen de forma única… y esto se extiende también a su destrucción. Cuando un hilo preemptivo está en funcionamiento, es importante no esperar a que otros objetos se destruyan dentro del método Destructor.
Sub Object1.Destructor() While Object2 <> Nil // La espera a que se destruya Object2 puede resultar en un deadlock, // especialmente si Object2 está siendo destruido en un hilo aparte. Wend End Sub
De igual modo, evita situaciones en las cuales están creando nuevos objetos mientras que estás en el método Destructor y haciendo una referencia a Self.
Sub Object1.Destructor() // Hacer una referencia a Self en un nuevo objeto puede resultar // en una secuencia recursiva del Destructor, causando un deadlock. Var newObj As New Class1 newObj.NotAGoodIdea = Self End Sub
Gestionar las condiciones de carrera
En Xojo 2024r3.1 creamos un ejemplo demostrando como sincronizar los recursos compartidos mediante el uso de secciones críticas y semáforos. Este ejemplo también destaca el efecto de una condición de carrera: tu app puede colgarse de inmediato, terminando la sesión de depuración sin ningún tipo de indicación sobre el lugar en el que ha ocurrido el cuelgue.
Estas violaciones de acceso no eran capturadas por nuestro depurador hasta ahora. Dado que estos cuelgues pueden interferir con lo mostrado en el depurador, hemos limitado de forma intencionada lo que se muestra, dado que la violación de acceso puede dejar a la app en un estado inestable. Aunque estas violaciones de acceso no son exclusivas a los cuelgues provocados por las condiciones de carrera, esta nueva característica tiene como objeto ayudarte a identificar las condiciones de carrera potenciales en tus apps cuando estás trabajando con hilos preemptivos. Vamos a echar un vistazo a dicho ejemplo y ver qué ocurre ahora cuando lo ejecutas desde el depurador:
Cuando haces clic en el botón diseñado para colgar de forma intencionada la app, ahora verás que vuelves al depurador donde se expone el nuevo icono de cuelgue 💣. Este símbolo indica que la app no puede proseguir (de ahí que todos los comandos de depuración están desactivados, y que los valores del depurador no se cargan… de modo que los objetos estarán a Nil). Tus únicas opciones en este punto son las de detener la app o bien intentar recargar los valores del depurador.
Haciendo clic en el botón de comando de la izquierda se refrescas o recargan los valores del depurador. Si la app es lo suficientemente estable, entonces los valores del depurador se refrescarán; de lo contrario, es probable que la app finalice de forma automática en este punto.
En resumen, estas mejoras están dirigidas a hacer que el uso de los hilos preemptivos sea más gratificante al ofrecer tanto una velocidad mejorada y también resulten más fáciles de procesar a la hora de identificar potenciales condiciones de carrera, lo cual anteriormente resultaba mucho más dificultoso. Al igual que sucede con el reto “One Billion Row Challenge”, ¡estamos deseando escuchar todas las formas en las que estás haciendo uso de los hilos preemptivos en tus apps!