View
3
Download
0
Category
Preview:
Citation preview
Practicas de Sistemas operativos
David Arroyo Guardeno
Escuela Politecnica Superior de la Universidad Autonoma de Madrid
Tercera Semana: Comunicacion entreprocesos con Tuberıas
1 Entregas
2 Introduccion
3 TuberıasEjemplo 1Ejemplo 2Ejemplo 3Ejemplo 4
Entregas
☠ Ejercicio 9☠☠ Entrega antes de la sesion del proximo
jueves 19 de febrero☠☠☠ Examen de la primera practica� : jueves
19 de febrero
Comunicacion entre procesos
Ø Formas elementales7 Envıo de senales7 Uso de ficheros ordinarios7 padre
ptrace−−−−→ hijo
Ø TuberıasØ Facilidades IPC del Unix System V
1 Semaforos2 Memoria compartida3 Colas de mensajes
Tuberıas
Canal de comunicacion entre dos procesos:semi-duplex
1 Tuberıas con nombre: FIFOS2 Tuberıas sin nombre
Tuberıas sin nombre I#include <unistd.h>int pipe(int fildes [2]);
Procesopadre
Nucleo(kernel)
Procesohijo
fd [1]
fd [0] fd1[0]
fd1[1]
7 Solo el proceso que hace la llamada ysus descendientes pueden utilizarla
7 fildes: descriptores de fichero3 Leemos (read) de fildes[0] (fichero de solo
lectura)3 Escribimos (write) en fildes[1] (fichero de
solo escritura)7 Tras fork /exec los hijos heredan los
descriptores de ficheros3 Abrimos la tuberıa en el padre3 Padre e hijo comparten la tuberıa
7 La tuberıa es gestionada por el nucleo3 La dota de una disciplina de acceso en hilera
3 Llamadas a read sobre la tuberıa nodevolveran el control hasta que no hayadatos escritos por otro proceso mediantewrite
#include <s t d i o . h>#include <s t d l i b . h>#include <errno . h>#include <un is td . h>#define MAX 256main ( ){
i n t tube [ 2 ] ;char message [MAX] ;i f ( p ipe ( tube ) == −1){
pe r ro r ( ” p ipe ” ) ;e x i t ( 1 ) ;
}
p r i n t f ( ” Wr i t i ng TO the f i l e w i th d e s c r i p t o r #%d\n ” , tube [ 1 ] ) ;w r i t e ( tube [ 1 ] , ”TEST” ,5 ) ;p r i n t f ( ” Reading FROM the f i l e w i th d e s c r i p t o r #%d\n ” , tube [ 0 ] ) ;read ( tube [ 0 ] , message , 5 ) ;p r i n t f ( ”READ DATA: \”%s \ ”\n ” ,message ) ;c lose ( tube [ 0 ] ) ;c lose ( tube [ 1 ] ) ;e x i t ( 0 ) ;
}
Ejemplo 2
Procesopadre
Nucleo(kernel)
Procesohijo
fd [1]
fd [0]
#include <s t d i o . h>#include <s t d l i b . h>#include <s t r i n g . h>
#define MAX 256main ( ){
i n t tube [ 2 ] ;i n t pid ;char message [MAX] ;
i f ( p ipe ( tube ) == −1){pe r ro r ( ” p ipe ” ) ;e x i t (−1) ;
}
i f ( ( p id = f o r k ( ) ) == −1) {pe r ro r ( ” f o r k ” ) ;e x i t (−1) ;
} else i f ( p id == 0){
/∗ Cier ra l a t u b e r i a de e s c r i t u r a porque no l a va a usar ∗ /c lose ( tube [ 1 ] ) ;while ( read ( tube [ 0 ] , message ,MAX)> 0 && strcmp ( message , ”END\n ” ) !=
0)p r i n t f ( ” \nrece ive r process . Message : %s\n ” ,message ) ;
e x i t ( 0 ) ;
} else {/∗ Cier ra l a t u b e r i a de l e c t u r a porque no l a va a usar ∗ /c lose ( tube [ 0 ] ) ;while ( p r i n t f ( ” sender process . message : ” ) !=0 && fge t s ( message ,
sizeof ( message ) , s t d i n ) != NULL && w r i t e ( tube [ 1 ] , message ,s t r l e n ( message ) + 1) > 0 && strcmp ( message , ”END\n ” ) !=0 ) ;
e x i t ( 0 ) ;}
}
Ejemplo 3
Procesopadre
Nucleo(kernel)
Procesohijo
tubetx [1]
tuberx [0] tubetx [0]
tuberx [1]
Comunicacion bidireccional Imain ( ){
i n t t u be t x [ 2 ] , t ube rx [ 2 ] ;i n t pid ;char message [MAX] ;
i f ( p ipe ( t ub e t x ) == −1| | pipe ( tube rx ) == −1){
pe r ro r ( ” p ipe ” ) ;e x i t (−1) ;
}
i f ( ( p id = f o r k ( ) ) == −1) {pe r ro r ( ” f o r k ” ) ;e x i t (−1) ;
} else i f ( p id == 0){
c lose ( t u be t x [ 1 ] ) ;c lose ( tube rx [ 0 ] ) ;while ( read ( t ub e t x [ 0 ] , message ,MAX)> 0
&& strcmp ( message , ”END\n ” ) != 0){p r i n t f ( ” \nrece ive r process . Message : %s\n ” ,message ) ;s t r cpy ( message , ”READY” ) ;w r i t e ( tube rx [ 1 ] , message , s t r l e n ( message ) + 1) ;
Comunicacion bidireccional II}
e x i t ( 0 ) ;
} else {c lose ( tube rx [ 1 ] ) ;c lose ( t u be t x [ 0 ] ) ;while ( p r i n t f ( ” sender process . message : ” ) !=0
&& fge t s ( message , sizeof ( message ) , s t d i n ) != NULL&& w r i t e ( t ub e t x [ 1 ] , message , s t r l e n ( message ) + 1) > 0 &&
strcmp ( message , ”END\n ” ) !=0 ) {do{
read ( tube rx [ 0 ] , message , MAX) ;} while ( strcmp ( message , ”READY” ) != 0) ;
}
e x i t ( 0 ) ;}
}
Duplicacion de descriptores de ficheros3 Si en la shell hacemos 2>&1
7 Por ejemplo, ¿que ocurre si hacemos losiguiente?
$ls -la . fichero_inventado >results.log 2>&1
7 La salida estandar de error (descriptor defichero= 2) es redirigida al mismo sitio al quese envıa la salida estandar (descriptor defichero=1
7 La shell efectua el redireccionamiento de lasalida estandar de error
1 Duplica el descriptor de fichero 22 Dicho descriptor ahora se refiere al mismo
fichero con descriptor 1
Duplicacion de descriptores de ficheros3 Si en la shell hacemos 2>&1
7 Por ejemplo, ¿que ocurre si hacemos losiguiente?
$ls -la . fichero_inventado >results.log 2>&1
7 La salida estandar de error (descriptor defichero= 2) es redirigida al mismo sitio al quese envıa la salida estandar (descriptor defichero=1
7 La shell efectua el redireccionamiento de lasalida estandar de error
1 Duplica el descriptor de fichero 22 Dicho descriptor ahora se refiere al mismo
fichero con descriptor 1
Duplicacion de descriptores de ficheros3 Si en la shell hacemos 2>&1
7 Por ejemplo, ¿que ocurre si hacemos losiguiente?
$ls -la . fichero_inventado >results.log 2>&1
7 La salida estandar de error (descriptor defichero= 2) es redirigida al mismo sitio al quese envıa la salida estandar (descriptor defichero=1
7 La shell efectua el redireccionamiento de lasalida estandar de error
1 Duplica el descriptor de fichero 22 Dicho descriptor ahora se refiere al mismo
fichero con descriptor 1
3 fcntl → man fcntl3 dup→ man dup3 dup2→ man dup2
Si la shell solo ha abierto los ficheros condescriptores 0,1, y el descriptor 2 se refiere alprograma en ejecucion y no existen otrosdescriptores
7 ¿Que hace la siguiente instruccion?newfd = dup(1);
3 Crea el duplicado del descriptor 1 usandoel fichero con descriptor 3
7 ¿Como puedo asociar el descriptor 2 anuestro duplicado?
3 Primero cierro el fichero con descriptor 2 yluego llamo a dup
Si la shell solo ha abierto los ficheros condescriptores 0,1, y el descriptor 2 se refiere alprograma en ejecucion y no existen otrosdescriptores
7 ¿Que hace la siguiente instruccion?newfd = dup(1);
3 Crea el duplicado del descriptor 1 usandoel fichero con descriptor 3
7 ¿Como puedo asociar el descriptor 2 anuestro duplicado?
3 Primero cierro el fichero con descriptor 2 yluego llamo a dup
Si la shell solo ha abierto los ficheros condescriptores 0,1, y el descriptor 2 se refiere alprograma en ejecucion y no existen otrosdescriptores
7 ¿Que hace la siguiente instruccion?newfd = dup(1);
3 Crea el duplicado del descriptor 1 usandoel fichero con descriptor 3
7 ¿Como puedo asociar el descriptor 2 anuestro duplicado?
3 Primero cierro el fichero con descriptor 2 yluego llamo a dup
close(2);newfd = dup(1);
⇒ En el ejemplo de antes bastarıa hacer
dup2(1,2);
#include <s t d l i b . h>#include <s t d i o . h>char ∗cmd1 [ ] = { ” / b in / l s ” , ”−a l ” , ” / ” , 0 } ; char ∗cmd2 [ ] = { ” / usr / b in /
t r ” , ” a−z ” , ”A−Z” , 0 } ;void run1 ( i n t tube [ ] ) ; void run2 ( i n t tube [ ] ) ;
i n t main ( i n t argc , char ∗∗argv ){
i n t pid , s ta tus ;i n t tube [ 2 ] ;
i f ( p ipe ( tube ) ==−1){f p r i n t f ( s tde r r , ” E r ro r en l a l i n e a %d del f i c h e r o %s\n ” , L INE ,
F ILE ) ;e x i t ( EXIT FAILURE ) ;
}run1 ( tube ) ;run2 ( tube ) ;c lose ( tube [ 0 ] ) ;c lose ( tube [ 1 ] ) ; /∗ Impor tante : hay que c e r r a r los dos desc r i p to res de
l a t u b e r i a ∗ /while ( ( p id = wa i t (& s ta tus ) ) != −1) /∗ Esperar a que hayan terminado
todos los h i j o s ∗ /f p r i n t f ( s tde r r , ” El proceso %d ha terminado y su estado de
f i n a l i z a c i o n es %d\n ” , pid , WEXITSTATUS( s ta tus ) ) ;e x i t (EXIT SUCCESS) ;
}
void run1 ( i n t tube [ ] ) /∗ Ejecu ta r l a pr imera par te de l a t u b e r i a ∗ /{
i n t pid ;switch ( p id = f o r k ( ) ) {case 0: /∗ h i j o ∗ /
dup2 ( tube [ 1 ] , 1) ; /∗ Cerramos e l d e s c r i p t o r 1 , l a s a l i d a estandar ,que pasa a ser l a s a l i d a de l a t u b e r i a ∗ /
c lose ( tube [ 0 ] ) ; /∗ Este proceso no neces i ta e l o t ro extremo de l at u b e r i a ∗ /
execvp (cmd1 [ 0 ] , cmd1) ; /∗ Ejecu ta r e l pr imer comando , cmd1 ∗ /pe r ro r (cmd1 [ 0 ] ) ; /∗ Estamos aqui so lo s i ha habido algun f a l l o ∗ /
defaul t : /∗ El padre no hace nada ∗ /break ;
case −1:pe r ro r ( ” f o r k ” ) ;e x i t ( EXIT FAILURE ) ;
}}
void run2 ( i n t t u b e r i a [ ] ) /∗ Se e jecu ta l a segunda par te de l a t u b e r i a ∗ /{
i n t pid ;switch ( p id = f o r k ( ) ){ case 0: /∗ h i j o ∗ /dup2 ( t u b e r i a [ 0 ] , 0) ; /∗ Este extremo de l a t u b e r i a pasa a ser l a
entrada estandar ∗ /c lose ( t u b e r i a [ 1 ] ) ; /∗ Extremo de t u b e r i a que no neces i ta este proceso
∗ /execvp (cmd2 [ 0 ] , cmd2) ; /∗ Se e jecu ta este comando ∗ /pe r ro r (cmd2 [ 0 ] ) ; /∗ Estoy aqui so lo s i ha producido algun e r r o r ∗ /defaul t : /∗ El padre no hace nada ∗ /
break ;case −1:
pe r ro r ( ” f o r k ” ) ;e x i t ( 1 ) ;
}}
Referencias
⇒ Francisco M. Marquez. Unix,Programacion Avanzada. Editorial:Ra-Ma. 3a Edicion. ISBN: 84-7897-603-5
Recommended