<img height="1" width="1" src="https://www.facebook.com/tr?id=1101141206686180&amp;ev=PageView &amp;noscript=1">

Cómo compartir datos y Mutexes LabVIEW 1

En LabVIEW, hay un montón de cosas bajo el capó que pueden afectar a cómo se ejecuta el código y, en última instancia, afectar a la funcionalidad de su código. ¿Alguna vez ha depurado algún código, ha activado la ejecución de resaltado y ha encontrado que otras piezas de código también se ejecutaban lentamente? ¿O has descubierto que a veces una rutina de tu código se ejecuta más lentamente cuando otro proceso [no relacionado] se está ejecutando?

Eso podría deberse al bloqueo, que es lo que hacen los mutex en determinadas circunstancias. Mutex es la abreviatura de un objeto de exclusión mutua, se utiliza para el arbitraje. Puede ser comparado con un palo que habla; a menudo un mutex se utiliza con recursos compartidos para controlar quién puede acceder a los datos compartidos. En LabVIEW, los mutexes son a menudo implícitos. Por ejemplo, un VI no reentrante utiliza un mutex implícito: sólo una instancia de este tipo de VI puede ejecutarse a la vez, por lo tanto, cuando dos instancias intentan ejecutarse simultáneamente, sólo una puede ejecutarse y la otra debe esperar hasta que la otra termine: una instancia se bloquea y la otra instancia tiene que esperar.

El bloqueo es a veces exactamente lo que quieres: un global funcional encapsula operaciones mientras modifica datos compartidos que podrían causar condiciones de carrera si el global funcional no se bloqueara. Pero también hay veces en las que el bloqueo puede dañar la eficiencia y tu código se ejecutará más lento cuando no tiene que hacerlo. Generalmente, la cantidad de tiempo que se produce el bloqueo es insignificante, excepto en situaciones en las que el código que se está bloqueando tarda una cantidad significativa de tiempo en ejecutarse.

Alternativamente, un VI reentrante no se bloqueará mientras otras instancias del mismo se estén ejecutando. Dos instancias de un VI reentrante pueden ejecutarse simultáneamente pero, si hay un VI contenido dentro (por profundo que sea) que no sea reentrante que intente ejecutarse simultáneamente, se bloqueará.

Tradicionalmente, los globales funcionales son siempre no reentrantes. Esto asegura que cada instancia del global funcional apunta exactamente al mismo espacio de memoria. Cuando no se utiliza la ejecución no reentrante, no hay una manera fácil de asegurar a qué ubicación de memoria está asociada cada instancia del VI, por lo tanto es difícil asegurar que se modifican datos comunes.

Hemos incluido tres ejemplos que proporcionan situaciones en las que los mutex están implicados, cómo puede afectar al tiempo de ejecución y cómo los modos de ejecución afectan a los globales funcionales. El código fuente está disponible aquí: lv_mutex_shared_1.zip

Ejemplo 01: Muestra la diferencia entre ejecución no reentrante y ejecución reentrante y cómo afecta al tiempo de ejecución.

lv-mutex-efficiency_1-example_1.png

Ejemplo 02: Muestra un ejemplo de dos VIs reentrantes ejecutándose simultáneamente con un VI no reentrante que intenta ejecutarse simultáneamente en cada instancia reentrante.

lv-mutex-efficiency_1-example_2.png

Ejemplo 03: Muestra cómo los diferentes tipos de modo de ejecución pueden afectar a los globales funcionales y cómo afecta a la ejecución de cada VI.

lv-mutex-efficiency_1-example_3.png

Algo de esto puede empujarte a preguntarte cómo puedes mantener la velocidad de ejecución reduciendo la dependencia de fuentes de datos no re-entrantes usando wires, pero eso también viene con sus propios problemas. Proveemos una solución a este tema en la próxima entrega de esta serie de blog!