MEMORIA COMPARTIDA Los procesos pueden comunicarse directamente entre sí compartiendo parte de su espacio de direcciones virtuales en la cual pueden escribir y leer datos, pasándose información de uno a otro de esta manera. La función shmget() es una llamada de sistema que crea una nueva región de memoria compartida o regresa una región ya existente. La llamada shmat() anexa de forma lógica una región de memoria compartida al espacio de direcciones virutales de un proceso. La llamada shmdt() desasocia una región de memoria compartida del espacio de direcciones virtuales de un proceso. La función shmctl() manipula varios parámetros asociados con la memoria compartida. Los procesos pueden escribir o leer datos en memoria compartida de la misma manera que lo hacen en memoria normal. Una vez que una región de memoria compartida es anexada, ésta se vuelve parte del espacio de direcciones virtuales del proceso. shmget() La sintaxis de la llamada de sistema shmget() es la siguiente: shmid = shmget(llave, tamaño, bandera); donde el tamaño especifica el número de bytes en la región. El kernel del sistema operativo busca la llave en la tabla de memoria compartida: si no la encuentra y la bandera es IPC_CREAT, se crea una nueva región y regresa un identificador de tipo entero; si la encuentra, regresa el identificador correspondiente a la región de memoria. shmat() Un proceso anexa una región de memoria compartida a su espacio de direcciones virtuales con la llamada de sistema shmat(). virtaddr = shmat(id, addr, banderas); id es el identificador de región de memoria regresado por una llamada anterior a shmget(), addr es la dirección virtual en donde el usuario desea anexar la región de memoria compartida, y banderas especifica las características de la región de memoria. Al ejecutar shmat(), el kernel verifica que el proceso tenga los permisos necesarios para acceder a la región. Examina la dirección provista por el usuario: si es 0, el kernel determina una dirección virtual conveniente. La memoria compartida no debe traslaparse con las regiones del espacio de direcciones virtuales. El valor virtaddr regresado por esta llamada es la dirección en la que el kernel anexó la memoria compartida, no necesariamente la dirección addr especificada por el usuario. virtaddr es un apuntador genérico (a ningún tipo de dato en especial, implementado en C comúnmente como un apuntador de tipo char), es decir: char *virtaddr; Para desasociar la región de memoria virtual del espacio de direcciones virtuales, se utiliza la llamada shmdt() como sigue: shmdt(virtaddr) shmctl() Un proceso usa la llamada de sistema shmclt() para solicitar el estatus y para ejercer una acción o establecer un parámetro para la memoria compartida. La sintaxis es: shmctl(id, cmd, shmstatbuf); id es el identificador de la región de memoria, cmd especifica el tipo de operación a realizar sobre la región de memoria compartida y shmstatbuf es la dirección de la estructura de usuario que contiene el estatus de la región de memoria al usar shmctl(). El siguiente programa crea una región de memoria compartida de 128 KB y la anexa dos veces en direcciones diferentes a su espacio de direcciones virtuales. Usando como referencia la primera dirección, addr1, el programa escribe datos en la memoria compartida. Usando la dirección addr2 accede a la región compartida para leer los datos escritos anteriormente. En el segundo programa, se tiene otro proceso que anexa la misma región de memoria compartida, aunque solamente 64 KB, lo cual es válido. Este segundo proceso espera a que el primero escriba un valor distinto a cero en la primera palabra, y entonces lee los datos almacenados en la memoria compartida. El primer proceso, correspondiente al primer programa, hace una pausa en espera a que el segundo proceso complete su operación. Cuando el primer proceso recibe una señal, remueve la región de memoria compartida. NOTA: La llamada de sistema signal(i, fcn) ejecuta la función de usuario especificada con la dirección fcn cuando se recibe la señal i. En el ejemplo, cuando una señal de entre 0 y 19 se recibe, se procede a eliminar la región de memoria compartida. Para correr dos procesos simultáneamente, se pueden correr los procesos en ventanas separadas, o uno de los procesos se puede ejecutar en el fondo anexando como postfijo el carácter & al nombre del proceso al ejecutarlo con un espacio intermedio. El otro proceso se ejecuta normalmente