Programación Concurrente
Act. 3 Reporte de investigación
a. Ejemplo de código en el que se evidencie una condición de carrera en su sección crítica y otro
en el que se muestre el principio de interbloqueo.
Código 1 en lenguaje C++:
/*
--> Condición de carrera <--
*/
#include <iostream>
#include <thread>
using namespace std;
int contador = 0;
void aumentar()
{
for (int i = 0; i < 1000000; i++)
{
contador++;
}
}
int main()
{
thread t1(aumentar);
thread t2(aumentar);
t1.join();
t2.join();
cout << "Valor final del contador: " << contador << endl; return
0;
}
Explicación:
En este código, tenemos dos hilos llamados t1 y t2, los cuales comparten la misma
variable "contador" y su tarea es incrementarla. Sin embargo, no se utiliza ningún
mecanismo de sincronización, como semáforos, para coordinar el acceso a la
variable. Esto significa que el resultado del contador puede ser incorrecto y cambiar
cada vez que se ejecute el código.
Código 2 en lenguaje C++:
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
mutex mtx;
void critical_section(int id)
{
for (int i = 0; i < 10; i++)
{ if (mtx.try_lock())
{
cout << "Hilo " << id << " entrando en la sección crítica." << endl;
// Simula alguna operación en la sección crítica
this_thread::sleep_for(chrono::milliseconds(100)); cout << "Hilo
" << id << " saliendo de la sección crítica." << endl;
mtx.unlock();
} else
{
cout << "Hilo " << id << " no pudo adquirir el bloqueo, intentando más tarde." <<
endl; this_thread::sleep_for(chrono::milliseconds(50)); // Espera antes de intentar de
nuevo
}
}
}
int main()
{
thread t1(critical_section, 1);
thread t2(critical_section, 2);
t1.join();
t2.join();
return 0;
}
Explicación:
En este caso, el mutex que se utiliza hace uso de la función try_lock(), algo así como
un guardián que controla el acceso. Este mecanismo permite que el hilo no quede
atrapado esperando indefinidamente para entrar a la sección crítica, como si fuera
una puerta que solo abre cuando está libre, evitando que el hilo quede bloqueado
mientras espera su turno.
Autómatas finitos deterministas:
Empecemos aclarando que estamos hablando de un modelo matemático, pero
enfoquémonos en su aplicación en programación. Los autómatas finitos
deterministas son ideales para modelar procesos secuenciales y sistemas reactivos.
Un ejemplo sencillo sería un semáforo con sus tres colores: es un buen ejemplo de
un autómata que sigue reglas claras y específicas.
Además, estos modelos nos ayudan a entender mejor el código que escribimos. Los
compiladores, por ejemplo, utilizan palabras clave, números y símbolos para
procesar el código y verificar si todo está bien estructurado. Imagínate cuando
ingresas un número de teléfono o un correo electrónico en un formulario: el sistema
sabe que debe seguir un formato específico, y es aquí donde los autómatas entran
en juego.
También son esenciales para motores de búsqueda como Google Chrome u otros
navegadores, ayudando a procesar y entender las consultas que realizamos.
Para explicar un poco más su funcionamiento, debemos entender que un autómata
tiene un estado inicial y un estado final. Mientras procesa la información, se mueve
entre estos estados siguiendo reglas, y si alcanza el estado final, significa que ha
reconocido un patrón válido. En pocas palabras, son máquinas que siguen reglas
simples para identificar patrones, y en programación son muy útiles porque nos
ayudan a crear programas más eficientes y confiables.
Ejercicios 1 y 2:
abbaa: Es aceptada
abb: No es aceptada
aba: Es aceptada
abaaaaa: es aceptada
abbbbbbaab: Es aceptada
Afirmación número 1:
Pues esto depende cuales sean los parámetros de aceptación del automata, por que si la
transición es con “a”, entonces pues hablamos de que sería verdadero y por consiguiente la
cadena es aceptada, pero a su contrario puede ser falsa si en los parámetros de aceptación
el autómata no tiene ningún saliente con “a” o si tiene ciclos que permiten alcanzar esos
parámetros sin terminar en “a” entonces pues en teoria seria falsa.
Afirmación número 2:
Si al leer “a” desde cualquier lado se llega al estado de aceptación pues la afirmación sería
verdadera pero esto significa que cualquier cadena que termine en “a” será aceptada, pero
puede ser falsa si al leer “a” desde cualquier punto no se alcanza este estado de aceptación
o si existen ciclos para evitar llegar a un estado que aunque la cadena acabe en “a” pues
entonces esto sería falso.
Conclusión:
Los modelos autómatas son bastante útiles en general y están ahí en distintas partes de
nuestras vidas, desde navegadores hasta aplicaciones, son una herramienta que
definitivamente podemos aprovechar para crear nuestras aplicaciones y conseguir un
funcionamiento más fluido.
Bibliografía:
● Fervari, R. (2020). Autómatas Finitos Deterministicos (DFA) [Archivo
PDF].
Recuperado de https://cs.famaf.unc.edu.ar/~rfervari/icc16/slides/class-1-slides.pdf