\subsection{Semáforos en Linux} \begin{frame} \frametitle{Comunicación, concurrencia y bloqueos} \framesubtitle{Semáforos en Linux} \begin{enumerate} \item<1-> Linux suporta dos tipos de semáforos: \begin{itemize} \item<2-> System V. \item<3-> POSIX. \end{itemize} \item<3-> Los semáforos tipos System V están diseñados para crear, manipular y mantener una gran cantidad de semáforos relacionados a través de un conjunto de los mismos. \item<4-> Los semáforos POSIX son una versión más simplificada, que permiten reconocer tanto hilos a nivel de usuario como hilos a nivel de kernel. \end{enumerate} \end{frame} \subsubsection{Semáforos System V} \begin{frame} \frametitle{Comunicación, concurrencia y bloqueos} \framesubtitle{Semáforos en Linux - System V} \begin{itemize} \item Un proceso crea un semáforo System V al realizar la llamada a sistema \texttt{semget}. \item La anterior llamada permite crear un conjunto de semáforos. \item Los procesos pueden ejecutar una sola operación sobre el conjunto del semáforo. \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Comunicación, concurrencia y bloqueos} \framesubtitle{Semáforos en Linux - System V} \begin{exampleblock}{Ejemplo de creación de un semáforo System V} {\footnotesize \begin{alltt} if ((sem = semget(keysem, 1, IPC_CREAT | IPC_EXCL)) == -1) \{ cerr << "Error: " << errno << endl; exit(1); \} union semun \{ int val; /* Value for SETVAL */ struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ unsigned short *array; /* Array for GETALL, SETALL */ struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */ \} semval; semval.val = 1; semctl(sem, 0, SETVAL, semval); \end{alltt} } \end{exampleblock} \end{frame} \begin{frame}[fragile] \frametitle{Comunicación, concurrencia y bloqueos} \framesubtitle{Semáforos en Linux - System V} \begin{block}{Semáforos System V} \begin{itemize} \item<1-> Los semáforos puede ser identificados a través de tres maneras: \begin{itemize} \item<2-> Semáforos nuevos y privados al procesos \texttt{IPC\_PRIVATE}. \item<3-> Das un valor específico de una clave entre dos o más procesos establece un identificador compartido. \item<4-> Es derivar una llave a partir de un nombre de ruta mediante la función ftok. \begin{alltt} #include #include key_t ftok(const char *path, int id); \end{alltt} \end{itemize} \end{itemize} \end{block} \end{frame} % \subsubsection{Semáforos POSIX} % \begin{frame} % \frametitle{Comunicación, concurrencia y bloqueos} % \framesubtitle{Semáforos en Linux - POSIX} % \begin{itemize} % \item Los semáforos en POSIX son de dos tipos: % \begin{itemize} % \item No nombrados. % \item Nombrados. % \end{itemize} % \item Los semáforos POSIX no nombrados son utilizados principalmente % en dentro de hilos que los pueden compartir como variables % globales. % \item También puede ser utilizados entre procesos que tiene % un mismo padre y se encarga de compartir el recurso entre % los procesos hijos. % \end{itemize} % \end{frame} % \begin{frame} % \frametitle{Comunicación, concurrencia y bloqueos} % \framesubtitle{Semáforos en Linux - POSIX} % \begin{itemize} % \item Los semáforos POSIX nombrados son utilizados principalmente % entre procesos independientes. % \item Estos semáforos utilizan un fichero como un representación % del semáforo entre los procesos. % \end{itemize} % \end{frame} % \begin{frame}[fragile] % \frametitle{Comunicación, concurrencia y bloqueos} % \framesubtitle{Semáforos en Linux - System V} % \begin{exampleblock}{Ejemplo de creación de un semáforo POSIX nombrado} % El siguiente ejemplo muestra como se inicializa un % árbol nombrado \texttt{argv[1]} y un valor inicial de 1. % {\footnotesize % \begin{alltt} % sem_t *sem; % if ((sem = sem_open(argv[1], 0, 0660, 0)) == SEM_FAILED) \{ % cerr << ``Error: `` << errno << endl; % exit(1); % \} % \end{alltt} % } % \end{exampleblock} % \end{frame} % \begin{frame}[fragile] % \frametitle{Comunicación, concurrencia y bloqueos} % \begin{exampleblock}{Semáforo no nombrados} % \begin{itemize} % \item<1-> La función \texttt{sem\_init} inicia un semáforo no nombrado. % \begin{alltt} % int sem_init(sem_t *sem, int pshared, unsigned int value); % \end{alltt} % \end{itemize} % \end{exampleblock} % \end{frame} % \subsection{Problemas clásicos de concurrencia} % \begin{frame}[fragile] % \frametitle{Problemas clásicos de concurrencia} % \framesubtitle{El problema del buffer limitado} % {\scriptsize % \begin{alltt} % {\sffamily\bfseries var} \textit{vacíos} = n, \textit{llenos} = 0, \textit{mutex} = 1: \textit{semáforo}; % \end{alltt} % \begin{multicols}{2} % \begin{center}\textbf{Productor}\end{center} % \begin{alltt} % {\sffamily\bfseries repeat} % \vdots % producir un elemento en \textit{sigp} % \ldots % \textit{wait}(\textit{vacíos}); % \textit{wait}(\textit{mutex}); % \vdots % \textit{signal}(\textit{mutex}); % \textit{signal}(\textit{llenos}); % {\sffamily\bfseries until} \textit{false}; % \end{alltt} % \begin{center}\textbf{Consumidor}\end{center} % \begin{alltt} % {\sffamily\bfseries repeat} % \textit{wait}(\textit{llenos}); % \textit{wait}(\textit{mutex}); % \vdots % quitar elemento del buffer y % ponerlo en \textit{sigc} % \vdots % \textit{signal}(\textit{mutex}); % \textit{signal}(\textit{vacíos}); % {\sffamily\bfseries until} \textit{false}; % \end{alltt} % \end{multicols} % } % \end{frame} % \begin{frame}[fragile] % \frametitle{Problemas clásicos de concurrencia} % \framesubtitle{El problema de los lectores y escritores (prioridad en los lectores)} % {\scriptsize % \begin{alltt} % {\sffamily\bfseries var} \textit{mutex} = 1, \textit{escr} = 1: \textit{semáforo}; % \textit{cuentalect} = 0: \textit{integer}; % \end{alltt} % \begin{multicols}{2} % \begin{center}\textbf{Estructura de un proceso escritor}\end{center} % \begin{alltt} % \textit{espera}(\textit{escr}); % \vdots % se realiza la escritura % \vdots % \textit{señal}(\textit{escr}); % \end{alltt} % \columnbreak % \begin{center}\textbf{Estructura de un proceso lector}\end{center} % \begin{alltt} % \textit{espera}(\textit{mutex}); % \textit{cuentalect} := \textit{cuentalect} + 1; % {\sffamily\bfseries if} \textit{cuentalect} = 1 % {\sffamily\bfseries then} \textit{espera}(\textit{escr}); % \textit{señal}(\textit{mutex}); % \vdots % se realiza la lectura % \vdots % \textit{espera}(\textit{mutex}); % \textit{cuentalect} := \textit{cuentalect} - 1; % {\sffamily\bfseries if} \textit{cuentalect} = 0 % {\sffamily\bfseries then} \textit{señal}(\textit{escr}); % \textit{señal}(\textit{mutex}); % \end{alltt} % \end{multicols} % } % \end{frame} % \begin{frame}[fragile] % \frametitle{Problemas clásicos de concurrencia} % \framesubtitle{El problema de los lectores y escritores (prioridad en los escritores)} % {\scriptsize % \begin{alltt} % {\sffamily\bfseries var} \textit{mutexclect} = 1, \textit{mutexcescr} = 1, \textit{mutex} = 1, % \textit{sescr} = 1, \textit{slect} = 1 : \textit{semáforo}; % \textit{cuentalect} = 0, \textit{cuentaescr} = 0: \textit{integer}; % \end{alltt} % \begin{multicols}{2} % \begin{center}\textbf{Estructura de un proceso escritor}\end{center} % \begin{alltt} % \textit{espera}(\textit{mutexcescr}); % cuentaescr := \textit{cuentaescr} + 1; % {\sffamily\bfseries if} \textit{cuentaescr} = 1 % {\sffamily\bfseries then} \textit{espera}(\textit{slect}); % \textit{señal}(\textit{mutexcescr}); % \textit{espera}(\textit{sescr}); % ESCRIBIRDATOS(); % \textit{señal}(\textit{sescr}); % \textit{espera}(\textit{mutexcescr}); % cuentaescr := \textit{cuentaescr} - 1; % {\sffamily\bfseries if} \textit{cuentaescr} = 0 % {\sffamily\bfseries then} \textit{señal}(\textit{slect}); % \textit{señal}(\textit{mutexcescr}); % \end{alltt} % \columnbreak % \begin{center}\textbf{Estructura de un proceso lector}\end{center} % \begin{alltt} % \textit{espera}(\textit{mutex}); % \textit{espera}(\textit{slect}); % \textit{espera}(\textit{mutexlect}); % \textit{cuentalect} := \textit{cuentalect} + 1; % {\sffamily\bfseries if} \textit{cuentalect} = 1 % {\sffamily\bfseries then} \textit{espera}(\textit{sescr}); % \textit{señal}(\textit{mutexlect}); % \textit{señal}(\textit{slect}); % \textit{señal}(\textit{mutex}); % LEERDATOS(); % \textit{espera}(\textit{mutextlect}); % \textit{cuentalect} := \textit{cuentalect} - 1; % {\sffamily\bfseries if} \textit{cuentalect} = 0 % {\sffamily\bfseries then} \textit{señal}(\textit{sescr}); % \textit{señal}(\textit{mutexlect}); % \end{alltt} % \end{multicols} % } % \end{frame} % \subsection{Problemas de concurrencia} % \begin{frame} % \frametitle{Problemas de concurrencia} % \framesubtitle{El jardin ornamental} % \begin{block}{El problema del jardin ornamental} % Un jardín ornamental está abierto a los miembros del público que % pueden entrar a través de dos torniquetes. El administrador % quiere determinar cuanta gente está en el jardín en cualquier % momento. % \end{block} % \end{frame} % \begin{frame} % \frametitle{Problemas de concurrencia} % \framesubtitle{El jardin ornamental limidado} % \begin{block}{El problema del jardin ornamental limitado} % Un jardín ornamental está abierto a los miembros del público que % pueden entrar a través de dos torniquetes. El administrador % quiere determinar cuanta gente está en el jardín en cualquier % momento. Pero existe un límite máximo $m$ de visitanes al sistema. % \end{block} % \end{frame} % \begin{frame} % \frametitle{Problemas de concurrencia} % \framesubtitle{El problema de los fumadores} % \begin{block}{El problema de los fumadores} % Considere un sistema con tres procesos \emph{fumador} y un % proceso \emph{agente}. Cada fumador pasa todo su tiempo enrollando % cigarillos y fumándolos. Sin embargo, para poder hacerlo, el fumador % necesita tres ingrediente: tabaco, papel y cerillas. Uno de los % procesos fumadores tiene papel, otro tabaco y el tercero tiene % cerillas. El agente tiene un abasto infinito de los tres materiales. % El agente coloca dos de los ingredientes en la mesa. Entonces, % el fumador que tiene el ingrediente faltante enrolla y fuma un % cigarillo, enviando una señal al agente cuando termina. A continuación, % el agente coloca otros dos de los tres ingredientes en la mesa, y el % ciclo se repite. Escriba