0% encontró este documento útil (0 votos)
14 vistas23 páginas

Comunicación entre Procesos en C

El documento detalla las técnicas de comunicación entre procesos en programación, incluyendo el uso de pipes, FIFO y memoria compartida. Se explican funciones como popen, pipe, mmap y shm_open, así como ejemplos prácticos de implementación. También se abordan aspectos de sincronización y gestión de memoria en sistemas Linux.

Cargado por

Naim Rejal
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
14 vistas23 páginas

Comunicación entre Procesos en C

El documento detalla las técnicas de comunicación entre procesos en programación, incluyendo el uso de pipes, FIFO y memoria compartida. Se explican funciones como popen, pipe, mmap y shm_open, así como ejemplos prácticos de implementación. También se abordan aspectos de sincronización y gestión de memoria en sistemas Linux.

Cargado por

Naim Rejal
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Universidad Tecnológica Nacional

Facultad Regional La Rioja

Técnicas Digitales III

- 2022-
Clase Anterior

● Clases con encuentros presenciales


⇨A distancia o en aula → Lunes de 21:00 a 23:00
⇨Videoconferencia l: https://zoom.us/j/86704574586
⇨Videoconferencia II: https://meet.google.com/qbd-rvjd-wqx
● Clases con encuentros no presenciales
⇨Autogestionadas en campus virtual
⇨https://frlr.cvg.utn.edu.ar/login/index.php

31/10/22 Ing. Ricardo F. Maldonado 2


Compartir datos

Pipes en consola y en procesos
– Lectura escritura popen( ); pclose( );

System call pipe( ) en proceso
– Pipe en procesos padre e hijo.

Comunicación FIFO – name pipe
– mkfifo( ); unlink( );

– lectura y escritura de fifo



Mapeo de memoria mmap( ); nummap( );

Memoria comprtida shm_open( ); shm_unlink( );
31/10/22 Ing. Ricardo F. Maldonado 3
Pipes


Término usado para referir la conexión de un stream de datos de un proceso
a otro. Generalmente se canaliza la salida de un proceso a la entrada de otro.

mediante comandos de shell, la salida de un proceso se alimente
directamente a la entrada de otro usando el carácter de canalización |

31/10/22 Ing. Ricardo F. Maldonado 4


Pipes en procesos

La forma más simple de pasar datos entre dos procesos es con las funciones
popen y pclose.
#include <stdio.h>
FILE *popen(const char *prog, const char *mode);
int pclose(FILE *stream_to_close);

popen permite que un programa invoque a otro como un nuevo proceso y pase
datos a el o recibir datos de el. prog es el programa a ejecutar, y mode debe ser
"r" o "w" .
– con "r" la salida del programa invocado se puede leer desde un FILE * (de
popen) con funciones de stdio.h
– con "w"; el programa invocado puede leer los datos en *FILE o el invocador
puede enviar datos al programa invocado usando funciones de stdio.h .

31/10/22 Ing. Ricardo F. Maldonado 5


Pipes en procesos – lee un pipe td3530.c

int main(){
FILE * fptr; La salida del comando uname va
...
al pipe fptr desde donde es leída y
puesta en buff
fptr = popen(“uname -a”, “r”);
if(fptr ) {
chars = fread(buff, sizeof(char),BUFSIZ,fptr);
if(chars> 0)
printf(“la salida es:-\n%s\n”, buffer);
pclose(fptr);
exit(EXIT_SUCCESS);
}
}
31/10/22 Ing. Ricardo F. Maldonado 6
Pipes en procesos td3531.c td3532.c

int main(){ Los datos se escriben al pipe fptr


FILE *fptr; desde el buff y son la entrada del
comando od
char buff[BUFSIZ + 1];
sprintf(buff, “Acá van los datos...\n”);
fptr = popen(“od -c”, “w”);
if(fptr != NULL)
fwrite(buff, sizeof(char),
strlen(buff), fptr);
pclose(fptr);
exit(EXIT_FAILURE);
}

31/10/22 Ing. Ricardo F. Maldonado 7


Syscall pipe

Crea un canal de datos unidireccional que permite la comunicación fifo


entre los extremos. Los datos escritos en el extremo de escritura
permanecen hasta que se leen desde el extremo de lectura.
#include <unistd.h>
int pipe(int pipefd[2]);

pipefd[2] son dos descriptores de los extremos del pipe. pipefd[0]
refiere al extremo de lectura y pipefd[1] refiere al de escritura.

Los elemento del arreglo son descriptores de archivos (no streams) y
para las lecura/escritura se utilizan las syscall read y write.

31/10/22 Ing. Ricardo F. Maldonado 8


Syscall pipe → en un proceso td3533.c


Se crea un canal con pipe( ).

Se escribe datos en el extremo pipefd[2]

Se lee datos en el extremo pipefd[0]

nd = write(pipefd[1],datos,strlen(datos));
nd = read(pipefd[0], buff, BUFSIZ);

31/10/22 Ing. Ricardo F. Maldonado 9


Syscall pipe → en procesos padre e hijo td3534.c


Se crea un canal con pipe( ).

Se crea un proceso hijo con fork.

El padre escribe datos y el hijo lee datos

31/10/22 Ing. Ricardo F. Maldonado 10


Syscall pipe → en procesos padre e hijo td3535a.c td3535b.c


El proceso consumidor es un programa diferente al productor (en lugar de un
proceso diferente del mismo programa).

exec( ) genera al nuevo proceso con el descriptor de archivo como parámetro

31/10/22 Ing. Ricardo F. Maldonado 11


Comunicación FIFO→ name pipe
Crea un archivo tipo pipe
$mkfifo my_fifo
$ls -l my_fifo

Leer desde el archivo FIFO:
$cat < my_fifo

Escribir el archivo FIFO :
● $echo > my_fifo "Hola"
$cat > my_fifo
$rm my_fifo

31/10/22 Ing. Ricardo F. Maldonado 12


Comunicación FIFO→ name pipe

Usa un (tipo) archivo (¡todo en Linux es un archivo!) en el filesystem como un pipe


al que pueden acceder diferentes procesos que lo abren para w/r.

Crea un archivo tipo pipe
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *filename, mode_t mode);

Eliminar el archivo pipe
#include <unistd.h> El modo se modifica según máscara de
usuario ( umask-022 -> creación de
int unlink(const char *pathname); archivos) el archivo resultante es 755 .

31/10/22 Ing. Ricardo F. Maldonado 13


Pipes con nombres → FIFO td3536.c

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(){
if(access(FIFO, F_OK) == -1{
int res= mkfifo(“/tmp/my_fifo”, 0600);
if(!res) puts(“FIFO createda”);
else exit(EXIT_SUCCESS);
res= unlink(“/tmp/my_fifo”);
}
}
31/10/22 Ing. Ricardo F. Maldonado 14
Pipes con nombres → FIFO


Al crear una FIFO se crea un archivo pero sin descriptor; por lo tanto se
debe generar este último para operar con él.
→ int open(const char *pathname, int flags, mode_t mode);
→ ssize_t read(int fd,void buf[count], size_t count);
→ ssize_t write(int fd,void buf[count], size_t count);
→ int close(int fd);
● PIPE_BUF valor definido por default para count

31/10/22 Ing. Ricardo F. Maldonado 15


Lectura y Escritura → FIFO td3536a.c td3536b.c


El comportamiento de read y write depende del modo como se abrió (open).
– read sin bloqueo (O_NONBLOCK ) esperará hasta que se puedan leer
datos y con bloqueo no esperará devolviendo 0 bytes.
– write con bloqueo esperará hasta que se puedan escribir los datos.

Si una FIFO se abrió bloqueado (O_WRONLY) el sistema garantiza la
escritura de PIPE_BUF o menos bytes

read( ) no puede aceptar todos los bytes que se escriben
❑ Falla si es de PIPE_BUF o menos bytes y no se pueden escribir los datos.
❑ Escribir parte, si es más de PIPE_BUF (devuelve los bytes escritos)

31/10/22 Ing. Ricardo F. Maldonado 16


HOMEWORK

Modificar según considere pertinente, los códigos de los programas
td3536x.c para que uno de ellos transmita comandos (productor) hacia el
otro (consumidor).

Usando un fifo ¿Podría confeccionar un programa que permita
implementar una comunicación bidireccional entre dos procesos? Y ¿entre
dos programas? En caso afirmativo, intente programarlo.

31/10/22 Ing. Ricardo F. Maldonado 17


Modelo de Memoria linux - mapeo
Espacio de
direcciones ●
La memoria (virtual) de cada proceso se divide en páginas
(direcciones designadas)
memoria

Mediante una callsystem un proceso puede obtener una
del proceso
sección de memoria con el fin de mapear en ella un archivo y
realizar operaciones R/W
memoria
del proceso ●
Un proceso puede determinar esa memoria como privada o
pública.
memoria –
mapeada Si es privada, el objeto mapeado no asume los cambios
que se hagan en el espacio mapeado. Lo contrario si es
pública.
– Se usa para realizar operaciones R/W sin usar las
memoria
del proceso funciones (privada)
– Sirve para comunicar dos o mas procesos (pública)
31/10/22 Ing. Ricardo F. Maldonado 18
Modelo de Memoria linux - mapeo
#include <sys/mman.h>
void * mmap(void addr[length], size_t length, int
prot, int flags,int fd, off_t offset);
int munmap(void addr[length], size_t length);

Devuelve la dirección de la nueva asignación (puntero)

Addr→ dirección del mapeo. Con NULL el kernel elige esas
posición

Length → tamaño del mapeo mayor a cero

Prot →PROT_EXEC; PROT_READ; PROT_WRITE; PROT_NONE

Flag → visibilidad MAP_SHARED; MAP_PRIVATE

Fd → file descriptor del archivo a mapear

Offset → posición del archivo en que se comienza a mapear

31/10/22 Ing. Ricardo F. Maldonado 19


Mapeo → ejemplo td3537.c

reemplazar un caracter por otro en un archivo.


fd=open(filename, O_RDWR);
fstat(fd,&statbuf);
addr=mmap(NULL,statbuf.st_size,PROT_WRITE,MAP_SHARED,fd,0);

printf("%s\n",addr);
for(i=0;i<statbuf.st_size; i++)
if(addr[i]==seekchar)
addr[1]=newchar;
printf("%s\n",addr);

31/10/22 Ing. Ricardo F. Maldonado 20


Memoria Compartida – objeto


Permite que dos o más procesos accedan a la misma memoria como si
todos llamaran a malloc y recibieran punteros a esa misma.

La memoria compartida es la forma más rápida de comunicación entre
procesos porque todos los procesos comparten la misma parte de
memoria. no requiere una llamada al sistema ni una entrada al kernel.
También evita duplicado de datos

Se debe proporcionar su propia sincronización ( un proceso no debe leer
de la memoria hasta que los datos se escriban allí y dos procesos no
deben escribir en la misma ubicación de memoria al mismo tiempo) →
semáforos.

Se representan en el file system → /dev/shm

Se compila con la biblioteca -lrt
31/10/22 Ing. Ricardo F. Maldonado 21
Memoria Compartida - objeto td3538a.c td3538b.c td3538c.c

#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
int shm_open(const char *name, int oflag, mode_t mode);
int shm_unlink(const char *name);
La función shm_open crea o abre un objeto de memoria compartida. Devuelve un descriptor de
archivo usado para acceder a la memoria compartida.
Name → nombre del objeto
Flags → O_RDONLY O_RDWR O_CREAT
Mode → permisos del archivo

31/10/22 Ing. Ricardo F. Maldonado 22


¿Preguntas?
¿Consultas?
¿Comentarios?
¿Aportes?
¿Sugerencias?

11/10/23 Ing. Ricardo F. Maldonado 23

También podría gustarte