Mecanismos de comunicación entre procesos (III)

por | abril 13, 2014

En esta entrada vamos a ver en qué consiste el siguiente IPC listado en la primera entrada de esta saga: mapped memory. Con este mecanismo podemos lograr comunicar procesos que se ejecutan en un mismo sistema operativo via un fichero compartido (usualmente este mecanismo se estudia como un modo de acceder de una forma rápida y fácil al contenido de ese fichero). Conceptualmente, es muy parecido a la memoria compartida. La función que se utiliza para mapear un fichero en memoria es mmap(), con el flag MAP_SHARED para que pueda ser compartida por varios procesos, y munmap() para el proceso inverso. El uso de estas funciones se puede consultar en la página man del sistema o en http://man7.org/linux/man-pages/man2/mmap.2.html

Ejemplo de uso

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#define FILE_LENGTH 0x1000
int main (int argc, char* const argv[])
{
 int fd;
 void* file_memory;
 char msg[10]="";
 int state,pid;
if ((pid=fork()) != -1) {
 if (pid == 0) {
 /* Open the file. */
 fd = open (argv[1], O_RDWR, S_IRUSR | S_IWUSR);
 write (fd, "", 10); /* The file can not be empty*/
 lseek (fd, 0, SEEK_SET);
 /* Create the memory mapping. */
 file_memory = mmap(0, FILE_LENGTH, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 close (fd);
 printf("Writingn");
 sprintf ((char*)file_memory, "%sn", "Message 1n");
 munmap (file_memory, FILE_LENGTH);
 }
 else {
 /* Open the file. */
 printf("Opening %sn", argv[1]);
 fd = open (argv[1], O_RDWR, S_IRUSR | S_IWUSR);
 lseek (fd, 0, SEEK_SET);
 /* Read the integer, print it out, and double it. */
 file_memory = mmap(0, FILE_LENGTH, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 if (file_memory!= NULL) {
 close (fd);
 printf("Wating child endn");
 /*wait(&state);*/
 sleep(1);
 printf("Readingn");
 sscanf(file_memory, "%9s", msg);
 printf("I've read: %sn", msg);
 sprintf ((char*)file_memory, "%sn", "Reaaadn");
 /* Release the memory */
 munmap (file_memory, FILE_LENGTH);
 wait(&state);
 }
 else {
 printf("mmap error");
 }
 }
 }
 else {
 printf("Error making child");
 }
exit(0);
}

Al ejecutar este código, podemos ver como la variable msg toma, en el código ejecutado por el padre,  el valor escrito en la memoria por el hijo («Message«).

Referencias:

  1. Advanced Linux Programming, de Mark Mitchell, Jeffrey Oldham y Alex Samuel