Sei sulla pagina 1di 48

Sist.

Operativos I

La concurrencia en Unix

La llamada fork()

Crea un nuevo proceso. Sintaxis: int fork () Descripcin: fork() crea un nuevo proceso. El nuevo proceso (proceso hijo) es una copia exacta del proceso que mando llamar a la funcin fork() excepto por lo siguiente: - El proceso hijo tiene un nico ID de proceso. El ID del proceso hijo no coincide con ningn ID de los procesos activos del grupo.

- El proceso hijo tiene un ID de proceso padre diferente. (el ID del proceso que mando llamar a la funcin fork).

Dr. Roberto Gmez

Diapo. No. 1

Sist. Operativos I

La concurrencia en Unix

Caractersticas del fork()

La funcin es llamada una vez, (por el padre), pero regresa dos veces: (a) una en el padre (b) una en el hijo Si algo sale mal regresa un -1 regresa id del hijo regresa el valor de 0

Dos posibles usos:


1. Proceso desea hacer una copia de s mismo: uno hace una operacin la copia realiza otra tarea Ejemplo: Servidores de redes

2. Proceso quiere ejecutar otro programa sin perder su contexto: Proceso crea una copia del proceso y la copia se encarga de ejecutar lo que quiera el proceso Ejemplo: shells

Dr. Roberto Gmez

Diapo. No. 2

Sist. Operativos I

La concurrencia en Unix

Primer ejemplo uso fork()

main ( ) { int i, j, n; float r=12.6; i = 123; j = 99; n= fork( ); printf (Hello \n); }

Dr. Roberto Gmez

Diapo. No. 3

Sist. Operativos I

La concurrencia en Unix

Diagrama ejecucin fork( )


Main() { int i, j, n; float r = -12.6; i = 123; j = 99; n = fork(); printf(hello\n); }

123 99 -12.6 hello\n datos

123 99 -12.6 hello\n copia de los datos

proceso padre cdigo compartido

proceso hijo

Dr. Roberto Gmez

Diapo. No. 4

Sist. Operativos I

La concurrencia en Unix

Tablas del kernel para la admon. de procesos

Tabla de textos y/o cdigos CODIGO Tabla de procesos

Nmero ltimo proceso creado

Nmero de procesos ejecutando el texto AREA U

15

HEAP STACK Informacin: -edo. proceso -swappe -tiempo residencia -prioridad DATOS

Nmero de proceso

NO SWAPPEABLE

SWAPPEABLE

Dr. Roberto Gmez

Diapo. No. 5

Sist. Operativos I

La concurrencia en Unix

Tablas del kernel para la admon. de procesos

Tabla de textos y/o cdigos

CODIGO

2 Tabla de procesos

Nmero ltimo proceso creado

15

10
Tabla de archivos abiertos

AREA U

AREA U

15

HEAP STACK DATOS

HEAP STACK DATOS

Copia

NO SWAPPEABLE

MEMORIA

SWAPPEABLE

Dr. Roberto Gmez

Diapo. No. 6

Sist. Operativos I

La concurrencia en Unix

Conociendo los identificadores de procesos

Los identificadores relacionados a un proceso pueden ser conocidos partir de las llamadas getpid y getppid int getpid() int getppid()

getpid() regresa el identificador del proceso que se est ejecutando en ese momento

getppid() regresa el identificador del padre del proceso que se est ejecutando

Dr. Roberto Gmez

Diapo. No. 7

Sist. Operativos I

La concurrencia en Unix

Cdigo programa exfork1.c


#include <stdio.h> main () { int n; if ((n= fork ()) == -1 ) { fprintf(stderr, Error en la creacin del proceso \n); exit (1); } else if (n = =0) { /* es un proceso hijo */ printf( Dentro proceso hijo con fork: %d \n,n); printf(Id. proceso hijo: %d\n, getpid()); } else { /* es un proceso padre */ printf(Dentro de proceso padre con fork: %d \n, n); printf(Id. procesos padre: %d \n, getpid()); printf(Fin proceso padre \n); } }

Dr. Roberto Gmez

Diapo. No. 8

Sist. Operativos I

La concurrencia en Unix

Ejemplo ejecucin exfork1.c


rogome@armagnac:241:>cc exfork1.c -o exfork1 rgomez@armagnac:242:>exfork1 Dentro proceso hijo con fork:0 Dentro proceso padre con fork: 5139 Id. proceso padre:5138 Fin proceso padre rogomez@armagnac:243:>Id. proceso hijo: 5139 rogomez@armagnac:243:>exfork1 Dentro proceso hijo con fork:0 Id. proceso hijo:5141 Dentro proceso padre con fork:5141 Id proceso padre:5140 Fin proceso padre rogomez@armagnac :244:>exfork1 Dentro proceso hijo con fork:0 Dentro proceso padre con fork:5145 Id. proceso padre: 5144 Fin proceso padre rogomez@armagnac:246:>Id. proceso hijo: 5145 rogomez@armagnac:246:>

Dr. Roberto Gmez

Diapo. No. 9

Sist. Operativos I

La concurrencia en Unix

Llamada sistema sleep()


Suspende la ejecucin de un proceso por un intervalo de tiempo especfico. Sintaxis: sleep(time) Descripcin: sleep suspende la ejecucin del proceso por un tiempo determinado especificado en segundos. Es utilizado para ejecutar un comando despus de un cierto tiempo, por ejemplo: sleep(50); comando; o para ejecutar un comando cada cierto tiempo, por ejemplo: while (1) { comando; sleep (37); }

Dr. Roberto Gmez

Diapo. No. 10

Sist. Operativos I

La concurrencia en Unix

Cdigo programa exfork2.c


#include<stdio.h> main( ) { int n; if ((n=fork()) = = -1 ) { fprintf(stderr,Error creacion hijo \n); exit(1); } else if (n= =0) { /* es un proceso hijo */ printf ( Dentro proceso hijo con fork: %d\n,n); sleep(5) printf( Id. proceso hijo: %d\n, getpid()); sleep(5); } else { /* es un proceso padre */ printf(Dentro proceso padre con fork: %d\n, n); sleep(5); printf( Id. proceso padre:% \n, getpid()); sleep(5); printf( Fin proceso padre \n); sleep(5); } }
Dr. Roberto Gmez Diapo. No. 11

Sist. Operativos I

La concurrencia en Unix

Ejemplo ejecucin exfork2.c


rogomez@armagnac:247:>cc exfork2.c -o exfork2 rogomez@armagnac:248>exfork2 Dentro proceso hijo con fork:0 Dentro proceso padre con fork: 5153 Id. proceso padre: 5152 Id. proceso hijo: 5153 Fin proceso padre rogomez@armagnac : 249:> /* Valor de sleep (hijo) =0 ; sleep (padre) = 5 */

rogomez@armagnac: 252:>exfork2 Dentro proceso hijo con fork:0 Dentro proceso padre con fork:5182 Id. proceso hijo: 5182 Id. proceso padre:5181 Fin proceso padre rogomez@armagnac:253:>exfork2 Dentro proceso hijo con fork:0 Id. proceso hijo:5184 Dentro proceso padre con fork:5184 Id. proceso padre:5183 Fin del proceso padre rogomez@armagnac :254:>
Dr. Roberto Gmez Diapo. No. 12

Sist. Operativos I

La concurrencia en Unix

Cdigo programa exph.c

#include<stdio.h> main() { int i, n; if ((n =fork()) = = -1) { fprintf(stderr,Error en creacin del proceso \n); exit(1); } else if (n= = 0) /* es un proceso hijo */ print(\t \tProceso hijo; id:% \n, getpid()); else /* es un proceso padre */ printf(Proceso PADRE; id:%d\n, getpid()); for (i=0; i< 3; i++) printf(Cdigo ejecutado por: %d\n, getpid()); }

Dr. Roberto Gmez

Diapo. No. 13

Sist. Operativos I

La concurrencia en Unix

Ejemplo ejecucin exph.c


rogomez@armagnac:140:>cc exph.c -o exph rogomez@armagnac:141:>exph Proceso hijo;id:2244 Proceso PADRE: id:2243 Cdigo ejecutado por:2243 Cdigo ejecutado por:2243 Cdigo ejecutado por:2243 rogomez@armagnac:142:>Cdigo ejecutado por:2244 Cdigo ejecutado por:2244 Cdigo ejecutado por:2244 rogomez@armagnac:142:>exph Proceso hijo;id:2246 Cdigo ejecutado por:2246 Cdigo ejecutado por:2246 Cdigo ejecutado por:2246 Proceso PADRE: id:2245 Cdigo ejecutado por:2245 Cdigo ejecutado por:2245 Cdigo ejecutado por:2245 rogomez@armagnac:143:>exph Proceso PADRE:id:2249 Proceso hijo: id:2250 Cdigo ejecutado por:2249 Cdigo ejecutado por:2249 Cdigo ejecutado por:2249 rogomez@armagnac:144:>
Dr. Roberto Gmez Diapo. No. 14

Sist. Operativos I

La concurrencia en Unix

Ejemplo ejecucin exph.c: (continuacin)


rogomez@armagnac:144:>Cdigo ejecutado por:2250 Cdigo ejecutado por:2250 Cdigo ejecutado por:2250 rogomez@armagnac:144:>exph Proceso PADRE: id:2260 Proceso hijo; id:2261 Cdigo ejecutado por:2261 Cdigo ejecutado por:2261 Cdigo ejecutado por:2261 Cdigo ejecutado por:2260 Cdigo ejecutado por:2260 Cdigo ejecutado por:2260 rogomez@armagnac:145:>exph Proceso hijo;id:2269 Cdigo ejecutado por:2269 Cdigo ejecutado por:2269 Cdigo ejecutado por:2269 Proceso PADRE;id:2268 Cdigo ejecutado por:2268 Cdigo ejecutado por:2268 Cdigo ejecutado por:2268 rgomez@armagnac:146:>

Dr. Roberto Gmez

Diapo. No. 15

Sist. Operativos I

La concurrencia en Unix

Cdigo programa padhijo7.c

#include<stdio.h> main() { int i,m,n; if ((n=fork()) = = -1) { fprintf(stderr,Error en la creacin de procesos \n); exit (1); } else if (n = =0) /* Es el hijo */ for (i=0;i<7; i++){ print(\t\t\t Proceso HIJO con id: %d, valor i: %d\n, getpid(),i); sleep(0); } else /* Es el padre */ for (i=0;i<7;; i++){ printf(Proceso PADRE con id:%d, valor i: %d\n, getpid(),i); sleep(0); } }

Dr. Roberto Gmez

Diapo. No. 16

Sist. Operativos I

La concurrencia en Unix

Ejemplo ejecucin padhijo.c (1/3)


rogomez@armagnac:26:>cc padhijo7.c -o padhijo7 rogomez@armagnac:27:>padhijo7 Proceso HIJO con id: 1923, valor i:0 Proceso PADRE con id: 1922, valor i:0 Proceso PADRE con id: 1922, valor i:1 Proceso PADRE con id: 1922, valor i:2 Proceso PADRE con id: 1922, valor i:3 Proceso PADRE con id: 1922, valor i:4 Proceso PADRE con id: 1922, valor i:5 Proceso PADRE con id: 1922, valor i:6 rogomez@armagnac:28:> Proceso HIJO con id: 1923, valor i:1 Proceso HIJO con id: 1923, valor i:2 Proceso HIJO con id: 1923, valor i:3 Proceso HIJO con id: 1923, valor i:4 Proceso HIJO con id: 1923, valor i:5 Proceso HIJO con id: 1923, valor i:6 rogomez@armagnac:28:>

Dr. Roberto Gmez

Diapo. No. 17

Sist. Operativos I

La concurrencia en Unix

Ejemplo ejecucin padhijo7.c (2/3)

rogomez@armagnac:28:>padhijo7 Proceso PADRE con id: 1928, valor i:0 Proceso PADRE con id: 1928, valor i:1 Proceso PADRE con id: 1928, valor i:2 Proceso PADRE con id: 1928, valor i:3 Proceso PADRE con id: 1928, valor i:4 Proceso PADRE con id: 1928, valor i:5 Proceso PADRE con id: 1928, valor i:6 rogomez@armagnac:29:>Proceso HIJO con id: 1929, valor i:0 Proceso HIJO con id: 1929, valor i:1 Proceso HIJO con id: 1929, valor i:2 Proceso HIJO con id: 1929, valor i:3 Proceso HIJO con id: 1929, valor i:4 Proceso HIJO con id: 1929, valor i:5 Proceso HIJO con id: 1929, valor i:6 rogomez@armagnac:30:>

Dr. Roberto Gmez

Diapo. No. 18

Sist. Operativos I

La concurrencia en Unix

Ejemplo ejecucin padhijo.c (3/3)

rogomez@armagnac:29:> padhijo7 Proceso HIJO con id: 1931, valor 1:0 Proceso HIJO con id: 1931, valor 1:1 Proceso HIJO con id: 1931, valor 1:2 Proceso HIJO con id: 1931, valor 1:3 Proceso HIJO con id: 1931, valor 1:4 Proceso HIJO con id: 1931, valor 1:5 Proceso HIJO con id: 1931, valor 1:6 Proceso PADRE con id: 1930, valor 1:0 Proceso PADRE con id: 1930, valor 1:1 Proceso PADRE con id: 1930, valor 1:2 Proceso PADRE con id: 1930, valor 1:3 Proceso PADRE con id: 1930, valor 1:4 Proceso PADRE con id: 1930, valor 1:5 Proceso PADRE con id: 1930, valor 1:6 rogomez@armagnac:30:>

Dr. Roberto Gmez

Diapo. No. 19

Sist. Operativos I

La concurrencia en Unix

Llamada sistema wait()

Espera que un proceso hijo termine. Sintaxis: int wait(n) int n Descripcin: Espera hasta que todos los procesos que se ejecutaron en background (con & o bg) terminen y reporta las terminaciones anormales. Ya que wait debe ser ejecutada en el proceso padre, el mismo shell ejecuta un wait, sin haber creado un nuevo proceso.

Dr. Roberto Gmez

Diapo. No. 20

Sist. Operativos I

La concurrencia en Unix

Cdigo programa exwait1.c

main() { int n: if ( (n=fork()) == -1) { fprintf(stderr, Error creacin proceso \n!); exit(1) } else if (n == 0) printf(Hijo \n); else { printf(Padre \n); wait(0); printf(Ya termino el hijo \n); } }

Dr. Roberto Gmez

Diapo. No. 21

Sist. Operativos I

La concurrencia en Unix

Ejemplo ejecucin exwait1.c


rogomez@armagnac:224:>exwait1 Hijo Padre Ya termino el hijo. rogomez@armagnac:225:>exwait1 Hijo Padre Ya termino el hijo rogomez@armagnac:226:>exwait1 Hijo Padre Ya termino el hijo romomez@armagnac:227>exwait1 Padre Hijo Ya termino el hijo rogomez@armagnac:228:>exwait1 Padre Hijo Ya termino el hijo rogomez@armagnac:229:>exwait1 Hijo Padre Ya termino el hijo rogomez@armagnac:230:>:
Dr. Roberto Gmez Diapo. No. 22

Sist. Operativos I

La concurrencia en Unix

Cdigo programa exwait2.c


main() { int n,i; if ((n=fork())==-1){ printf(Error en el fork() \n); exit(1); } else if (n = = 0){ for (i=1;i<=5; i++){ printf(hijo id: %d, valor de i:%d \n,getpid(),i); sleep(1); } exit(0); } else{ printf( Prueba del wait: ANTES del for \n); /*POS 1*/ /* wait(0); */ for (i=1; i<=5; i++){ printf(\t\t PADRE id: %d, valor i: %d\n,getpid(),i); sleep(0); } /* POS 2*/ wait(0); printf(Prueba del wait: DESPUES del for \n); } }
Dr. Roberto Gmez Diapo. No. 23

Sist. Operativos I

La concurrencia en Unix

Ejemplo ejecucin exwait2.c, (en pos1)


rogomez@armagnac:39:>exwait2 Prueba del wait: ANTES del for hijo id:484, valor de i :1 hijo id:484, valor de i :2 hijo id:484, valor de i :3 hijo id:484, valor de i :4 hijo id:484, valor de i :5 PADRE id:483, valor i:1 PADRE id:483, valor i:2 PADRE id:483, valor i:3 PADRE id:483, valor i:4 PADRE id:483, valor i:5 Prueba del wait: DESPUES del for rogomez@armagnac:40:>exwait2 hijo id:486, valor de i:1 Prueba del wait: ANTES del for hijo id:486, valor de i:2 hijo id:486, valor de i:3 hijo id:486, valor de i:4 hijo id:486, valor de i:5 PADRE id:485, valor i:1 PADRE id:485, valor i:2 PADRE id:485, valor i:3 PADRE id:485, valor i:4 PADRE id:485, valor i:5 Prueba del wait: DESPUES del for rogomez @armagnac:41: >
Dr. Roberto Gmez Diapo. No. 24

Sist. Operativos I

La concurrencia en Unix

Ejemplo ejecucin exwait2.c, (en pos 1) (continuacin)

rogomez @armagnac:41: >exwait2 hijo id: 488, valor de i:1 hijo id: 488, valor de i:2 hijo id: 488, valor de i:3 hijo id: 488, valor de i:4 hijo id: 488, valor de i:5 Prueba del wait: ANTES del for PADRE id:487, valor de i:1 PADRE id:487, valor de i:2 PADRE id:487, valor de i:3 PADRE id:487, valor de i:4 PADRE id:487, valor de i:5 Prueba del wait: DESPUES del for rogomez @armagnac:42:>

Dr. Roberto Gmez

Diapo. No. 25

Sist. Operativos I

La concurrencia en Unix

Ejemplo ejecucin exwait2.c, (en pos2)


rogomez @armagnac:132: >exwait2 Prueba del wait:ANTES del for PADRE id: 524, valor i: 1 PADRE id: 524, valor i: 2 PADRE id: 524, valor i: 3 PADRE id: 524, valor i: 4 PADRE id: 524, valor i: 5 hijo id:527, valor de 1:1 hijo id: 527, valor de i:2 hijo id: 527, valor de i:3 hijo id: 527, valor de i:4 hijo id: 527, valor de i:5 Prueba del wait: DESPUES del for rogomez @armagnac:133: >exwait2 hijo id:527, valor de 1:1 Prueba del wait: ANTES del for PADRE id: 526, valor i:1 PADRE id: 526, valor i:2 PADRE id: 526, valor i:3 PADRE id: 526, valor i:4 PADRE id: 526, valor i:5 hijo id: 527, valor de i:2 hijo id: 527, valor de i:3 hijo id: 527, valor de i:4 hijo id: 527, valor de i:5 Prueba del wait: DESPUES del for rogomez @armagnac:134>
Dr. Roberto Gmez Diapo. No. 26

Sist. Operativos I

La concurrencia en Unix

Ejemplo ejecucin exwait2.c, (en pos2) (continuacin)

rogomez @armagnac:134: >exwait2 hijo id: 529, valor de i:1 Prueba del wait: ANTES del for PADRE id: 528, valor i:1 PADRE id: 528, valor i:2 PADRE id: 528, valor i:3 PADRE id: 528, valor i:4 PADRE id: 528, valor i:5 hijo id: 529, valor de i:2 hijo id: 529, valor de i:3 hijo id: 529, valor de i:4 hijo id: 529, valor de i:5 Prueba del wait: DESPUES del for rogomez @armagnac:135: >

Dr. Roberto Gmez

Diapo. No. 27

Sist. Operativos I

La concurrencia en Unix

La llamada sistema exit()


Termina la ejecucin de un proceso Sintaxis: void exit(estatus) int estatus; Descripcin: - Descriptores abiertos por los procesos son cerrados

- Nunca regresa al que lo llamo.


- Una seal SIGCHLD es enviada al padre. - Si el padre activ la bandera SA_NOCLWAIT, el estatus no est disponible para el padre. El id del padre es -1 y el proceso de inicializacin es heredado al hijo. - Si no est activa la bandera SA_NOCLWAIT: + El proceso se vuelve zombie hasta que el padre ejecuta un wait() o waitpid() + Si el padre ejecuta un wait() o waitpid() el estado de terminacin est disponible para el padre
Dr. Roberto Gmez Diapo. No. 28

Sist. Operativos I

La concurrencia en Unix

Relacin entre las llamadas wait() y exit() + Verificacin del estatus de terminacin de un proceso. + Usar primitiva wait():

int wait(int *n)


+ Provoca la suspencin del proceso hasta que uno sus hijos termine. + Tambin se puede usar para esperar un evento (seales). + Si el proceso hijo termina antes ejecucin wait ste se vuelve zombie. + Regreso del wait es inmediato: - nmero proceso a quien esperaba el wait() - cdigo de regreso a travs del parmetro + Regresa -1 si no hay hijos + Si n es diferente de cero, *n contiene informacin sobre el tipo de terminacin del proceso hijo.
Dr. Roberto Gmez Diapo. No. 29

Sist. Operativos I

La concurrencia en Unix

Status de terminacin

Si termin normalmente
Los ocho bits ms significativos *n reciben el valor de 8 bits menos significativos del parmetro exit() y los otros ocho bits son cero.

Si termin por la llegada de una seal


Los 8 bits menos significativos de *n reciben el nmero de la seal sumada a 02008 (12810), si es que esta seal genera un core.

Dr. Roberto Gmez

Diapo. No. 30

Sist. Operativos I

La concurrencia en Unix

Ejemplo terminacin normal


Cdigo toto.c: main() { if (fork() == 0) { printf(Proceso hijo id: %d \n, getpid()); exit(3); } else{ int m,n; m= wait (&n); printf( Fin del proceso %d valor regreso: %d n,m,n); } Ejemplo corrida: $cc toto.c -o toto $toto Proceso hijo id: 9227 Fin del proceso 9227 valor regreso: 768 $ 76810= 00000011000000002
Dr. Roberto Gmez Diapo. No. 31

Sist. Operativos I

La concurrencia en Unix

Ejemplo Terminacin Anormal


Cdigo cachafas.c: main() { if (fork( ) = = 0) { printf(Id. proceso hijo: %d n, getpid()); for(;;); } else { int m,n; m = wait (&n); printf(Fin del proceso %d valor regreso: %d n, m,n); } $cc cachafas.c-o cachafas $cachafas & Id. proceso hijo id: 9286 $kill -9 9286 Fin del proceso 9286 valor regreso: 9 $cachafas & Id proceso hijo id: 9290 $kill -5 9290 Fin del proceso 9290 valor regreso: 133 (se crea un core)
Dr. Roberto Gmez Diapo. No. 32

Sist. Operativos I

La concurrencia en Unix

La llamada waitpid()
Espera a que el proceso hijo cambie de estado. Sintaxis: #include <sys/types.h> #include <sys/wait.h> pid_t waitpid(pid_t pid, int *stat_loc, int options); Descripcin: Suspende la ejecucin del proceso hasta que uno de sus hijos cambia de estado. Si el proceso hijo cambia de estado antes de la llamada waitpid(), el regreso es inmediato. Parmetro stat_loc recupera el status de terminacin del proceso que se espera Parmetro options especifica opciones de espera Parmetro pid especifica un conjunto de procesos hijos de los cuales se est solicitando el estatus. Si es igual a Igual a -1 .- Se pide el estatus de cualquier hijo. Mayor que 0.- Especifica el identificador del proceso hijo del que se solicita el estatus. Igual a 0 .- Se solicita el estatus de cualquier proceso hijo cuyo identificador de grupo sea igual al del proceso que lo mand llamar. Menor que -1 .- Solicita el estatus de cualquier proceso hijo cuyo identificador de grupo sea el valor absoluto del valor de pid.
Dr. Roberto Gmez Diapo. No. 33

Sist. Operativos I

La concurrencia en Unix

Valores que regresa:

Si regresa porque el estatus del proceso hijo est disponible entonces regresa un valor igual al identificador del proceso hijo cuyo estatus se est reportando.

Si regresa debido al arribo de una seal al proceso padre, el valor de -1 es regresado y errno se asigna a EINTR.

Si fue invocada con WNOHANG como opcin, y no est disponible el estatus de al menos un proceso especificado en pid se regresa el valor de 0.

De otra manera, el valor de -1 es regresado, y errno indica el error ocurrido.

Dr. Roberto Gmez

Diapo. No. 34

Sist. Operativos I

La concurrencia en Unix

Ejemplo de uso de waitpid()


// Dado tres procesos hijos, espera que el segundo termine int uno, dos, tres; int retval; int *status; int tmp; /*identificadores procesos creados */ /* valor de regreso de la llamada waitpid() */ /* valor status terminacion proceso hijo */ /* tiempo a dormir de los procesos */

if ( (uno = fork()) == 0) { /* primer hijo */ tmp = (random()%10); printf(Proceso uno (%d) a dormir %d sgs \n, getpid(), tmp); sleep(tmp); printf(Proceso uno termino \n); } else if ( (dos = fork()) == 0) { /* segundo hijo */ tmp=(random()%10); printf(\t Proceso dos (%d) a dormir %d sgs \n, getpid(), tmp); sleep(tmp); printf(\t Proceso dos termino \n); } else if ( (tres = fork()) == 0) { /* tercer hijo */ tmp=(random()%10); printf(\t\t Proceso tres (%d) a dormir %d sgs \n, getpid(), tmp); sleep(tmp); printf(\t\t Proceso tres termino \n); }
Dr. Roberto Gmez Diapo. No. 35

Sist. Operativos I

La concurrencia en Unix

else {

/* Codigo proceso padre */ printf(\t\t\t Esperando que el proceso dos, (%d) termine, dos); retval = waitpid(dos, &status, 0); printf(\t\t\t Proceso dos (%d) , retval); printf(termino con status: %d \n, status);

} }

Dr. Roberto Gmez

Diapo. No. 36

Sist. Operativos I

La concurrencia en Unix

Ejemplo ejecucin
rogomez@armagnac:330>cc exwaitpid.c -o corre rogomez@armagnac:331>corre Proceso uno (4292) a dormir 3 segs. Proceso dos (4293) a dormir 3 segs. Proceso tres (4294) a dormir 3 segs. Esperando que el proceso dos termine Proceso uno termino Proceso dos termino Proceso dos (4293) termino con estatus: 256 rogomez@armagnac:332> Proceso tres termino rogomez@armagnac:332>corre Proceso dos (4297) a dormir 3 segs. Proceso uno (4296) a dormir 3 segs. Proceso tres (4298) a dormir 3 segs. Esperando que el proceso dos termine Proceso dos termino Proceso dos (4297) termino con estatus: 256 Proceso uno termino rogomez@armagnac:333> Proceso tres termino rogomez@armagnac:333>corre Proceso dos (4306) a dormir 3 segs. Proceso tres (4307) a dormir 3 segs. Esperando que el proceso dos termine Proceso uno (4305) a dormir 3 segs. Proceso dos termino Proceso dos (4306) termino con estatus: 256 rogomez@armagnac:334> Proceso tres termino Proceso uno termino rogomez@armagnac:334>
Dr. Roberto Gmez Diapo. No. 37

Sist. Operativos I

La concurrencia en Unix

La llamada sistema exec()


Provoca que el proceso substituya la imagen de ejecucin con la de un nuevo programa.

Sintaxis: Depende de los argumentos a pasar.


Descripcin: Proceso pierde el contexto que tena asociado con el antiguo programa. Proceso no pierde si pid, ni el de su padre, y continua con su papel de hijo. Lo nico que retiene el proceso de su contexto son los descriptores de archivos abiertos. Existen seis versiones de exec() que varan segn: 1. Especificacin programa a ejecutar 2. Ambiente ejecucin 3. Paso de argumentos
Dr. Roberto Gmez Diapo. No. 38

Sist. Operativos I

La concurrencia en Unix

Arbol decisin para la llamada exec()

Ruta de acceso, (pathname) del ejecutable.


Absoluta Relativa

Ambiente?
Heredada Nueva

Ambiente?

Nueva

Heredada

Argumentos?
Lista explcita

Argumentos?
Lista explcita

Inexistente Argumentos?
Vector Arreglo Lista explcita Vector Arreglo

Vector Arreglo

execl()

execv() execle()

execve()

execlp() execvp()

Dr. Roberto Gmez

Diapo. No. 39

Sist. Operativos I

La concurrencia en Unix

Declaracin de Familias exec()

int execl(path, arg0, arg1, ...., argn, (char)*0) char*path, *arg0, *arg1, ...., *argn int execv(path, argv) char *path, *argv[] int execle (path, arg0, arg1, ..., argn, (char)*0, envp) char *path, *arg0, *arg1, ..., *argn, *envp[] int execve (path, argv, envp) char *path, *argv[], *envp[] int execlp (file, arg0, arg1, ..., argn, (char)*0) char *file, *arg0, *arg1, ..., *argn int execvp (file, argv) char *file, *argv[] envp - Arreglo de apuntadores a caracteres que constituyen el ambiente en el que se va ejecutar el nuevo programa. Termina con un apuntador a NULL.
Dr. Roberto Gmez Diapo. No. 40

Sist. Operativos I

La concurrencia en Unix

Parmetros del main

main (argc, argv, envp)

Nmero de argumentos

Argumentos del command line

Variables de ambiente

grep benito directorio

HOME: /home/dic/rogomez DISPLAY: egarac:0.0 SHELL: /usr/bin/sh HOST: armagnac

Dr. Roberto Gmez

Diapo. No. 41

Sist. Operativos I

La concurrencia en Unix

Cdigo ejemplo

int main (int argc, char *argv[], char *env[]) { int i;


for (i=0; i<argc; i++) { printf("Argumento %d: %s\n", i, argv[i]); } i = 0; while(env[i]) { printf ("%s\n", env[i++]); }

Dr. Roberto Gmez

Diapo. No. 42

Sist. Operativos I

La concurrencia en Unix

Ejecucin cdigo
rogomez@armagnac:205>gcc args2.c -o args2 rogomez@armagnac:206>args2 uno dos tres Argumento 0: args2 Argumento 1: uno Argumento 2: dos Argumento 3: tres _=/usr/local/bin/tcsh SESSIONTYPE=altDt DTXSERVERLOCATION=local LANG=en_US HELPPATH=/usr/openwin/lib/locale:/usr/openwin/lib/help PATH=.:/home/rogomez:/usr/local/tex/bin/sparc-sun-solaris2.6: WINDOW_TERMIOS= DISPLAY=:0.0 : : GROUP=unknown HOST=armagnac.cem.itesm.mx : : MSDOS_CMDS=/usr/local/mtools IOFFICE_ROOT=/usr/local/ioffice/bin rogomez@armagnac:207>

Dr. Roberto Gmez

Diapo. No. 43

Sist. Operativos I

La concurrencia en Unix

Ejemplo: execlp

Se desea ejecutar sort con argumentos -n y foo La llamada sera:

Argumentos

execlp (sort, sort, -n, foo, 0)

Nombre del comando

Primer argumento (argv[0])

Marca del fin de la lista

Dr. Roberto Gmez

Diapo. No. 44

Sist. Operativos I

La concurrencia en Unix

Primer ejemplo uso llamada execlp()

// Programa que imprime un menu de comandos y ejecuta el // comando seleccionado #include <stdio.h> main() { /*lista de comandos */ static char *cmd[] = {who, ls, date}; int i; printf(0>who 1>ls 2>date ); scanf(%d, &i); execlp(cmd[i], cmd[i], 0); printf(No se encontr el comando seleccionado \n); }

Dr. Roberto Gmez

Diapo. No. 45

Sist. Operativos I

La concurrencia en Unix

Segundo ejemplo uso llamada execlp()


//Crea proceso que ejecuta comando pasado como argumento de comando lnea

#include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdio.h> #include <errno.h> main(int argc, char *argv[]) { int estatus; pid_t idhijo, waitreturn; if ((idhijo = fork()) == -1) { fprintf(stderr, Error en el fork \n); exit(1); } else if (idhijo == 0) { if (execlp(argv[1], argv[1], 0) < 0) { fprintf(stderr, Error en la ejecucion de %s \n, argv[1]); exit(1); } } else while ( idhijo != (waitreturn = waitpid (-1, &status, WNOHANG))) if ( !((waitreturn == -1) && (errno != EINTR)) ) break; exit(0); }
Dr. Roberto Gmez Diapo. No. 46

Sist. Operativos I

La concurrencia en Unix

Ejemplo uso execvp()

#include <errno.h> char *argv[10]; main() { /* comando = ls l tarea* argv[0]="ls"; argv[1]="-l"; argv[2]="tarea*"; argv[3]=(char *)0; */

printf("Contenido directorio: \n");


execvp(argv[0],argv); printf("Error %d en el argv \n",errno); }

Dr. Roberto Gmez

Diapo. No. 47

Sist. Operativos I

La concurrencia en Unix

Ejemplo uso execle()


#include <stdio.h> #include <sys/types.h> #include <sys/wait.h> #include <errno.h> char *env_init[] = {"USER=unknown", "PATH=/tmp", NULL}; int main() { pid_t pid;

if ( (pid = fork()) < 0 ) fprintf(stderr,"Error en el fork() \n"); else if (pid == 0) { execle("/usr/bin/uname", "-a", (char *)0, env_init); fprintf(stderr,"Error %d en el execle() \n",errno); exit(1); } if ( waitpid(pid,NULL,0) < 0 ) fprintf(stderr,"Error en el wait() \n"); printf("Fin del ejemplo \n"); exit(0);
} rogomez@armagnac:243>gcc ej-execle.c -o ejemplo rogomez@armagnac:244>ejemplo SunOS Fin del ejemplo rogomez@armagnac:245>
Dr. Roberto Gmez Diapo. No. 48

Potrebbero piacerti anche