You are on page 1of 44

Sist. operativos.

La concurrencia

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).

Diapo. No. 1
Sist. operativos. La concurrencia

Caractersticas del fork()

La funcin es llamada una vez, (por el padre), pero regresa


dos veces:

(a) una en el padre regresa id del hijo


(b) una en el hijo regresa el valor de 0

Si algo sale mal regresa un -1

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

Diapo. No. 2
Sist. operativos. La concurrencia

Primer ejemplo uso fork()

main ( )
{
int i, j, n;
float r=12.6;

n= fork(
f k( );)
printf (Hello \n);

Diapo. No. 3
Sist. operativos. La concurrencia

Diagrama ejecucin fork( )

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

copia
datos de los
datos

proceso
padre pproceso
cdigo compartido hijo

Diapo. No. 4
Sist. operativos. La concurrencia

Tablas del kernel para la


admon. de procesos

Tabla de
textos y/o cdigos

CODIGO

Tabla de procesos

Nmero ltimo Nmero de procesos


proceso creado ejecutando el texto

15 AREA U

HEAP
STACK
DATOS
Informacin:
-edo. p
proceso
Nmero dde
N
-swappe
proceso
-tiempo residencia
-prioridad

NO SWAPPEABLE SWAPPEABLE

Diapo. No. 5
Sist. operativos. La concurrencia

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 AREA U AREA U

Tabla
T bl de
d
15 archivos HEAP HEAP
abiertos
STACK STACK
DATOS DATOS

2 Copia

NO SWAPPEABLE MEMORIA SWAPPEABLE

Diapo. No. 6
Sist. operativos. La concurrencia

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
j d

Diapo. No. 7
Sist. operativos. La concurrencia

Cdigo programa exfork1.c

#include <stdio.h>
main ()
{
i t n;
int

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.
i f(Id procesos padre:
d %d \n,\ getpid());
id())
printf(Fin proceso padre \n);
}
}

Diapo. No. 8
Sist. operativos. La concurrencia

Ejemplo ejecucin exfork1.c

ajjaajj@armagnac:241:>cc exfork1.c -o exfork1


ajjaajj@armagnac:242:>exfork1
Dentro proceso hijo con fork:0
Dentro proceso padre con fork: 5139
Id proceso padre:5138
Id. d 5138
Fin proceso padre
ajjaajj@armagnac:243:>Id. proceso hijo: 5139

ajjaajj@armagnac:243:>exfork1
Dentro proceso hijo con fork:0
Id. proceso hijo:5141
Dentro proceso padre con fork:5141
Id pproceso padre:5140
p
Fin proceso padre
ajjaajj@armagnac :244:>exfork1
Dentro proceso hijo con fork:0
Dentro proceso padre con fork:5145
Id. proceso padre: 5144
Fin proceso padre
ajjaajj@armagnac:246:>Id. proceso hijo: 5145

ajjaajj@armagnac:246:>

Diapo. No. 9
Sist. operativos. La concurrencia

Llamada sistema sleep()

Suspende
S d lla ejecucin
j i de
d un proceso por un intervalo
i t l de
d
tiempo especfico.

Sintaxis:
sleep(time)

Descripcin:
sleep suspende la ejecucin del proceso por un tiempo
determinado especificado
p en segundos.
g Es utilizado ppara
ejecutar un comando despus de un cierto tiempo, por
ejemplo:

sleep(50);
comando;
d

o para ejecutar un comando cada cierto tiempo, por


ejemplo:

while (1)
{
comando;
ssleep
eep (37);
}

Diapo. No. 10
Sist. operativos. La concurrencia

Cdigo programa exfork2.c

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

Ejemplo ejecucin exfork2.c

ajjaajj
jj jj@armagnac:247:>cc
247 exfork2.c
f k2 -o exfork2
f k2
ajjaajj@armagnac:248>exfork2
Dentro proceso hijo con fork:0
Dentro proceso padre con fork: 5153
Id proceso padre: 5152
Id.
Id. proceso hijo: 5153
Fin proceso padre
ajjaajj@armagnac : 249:>

/* Valor de sleep (hijo) =0 ; sleep (padre) = 5 */

ajjaajj@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
ajjaajj@armagnac:253:>exfork2
Dentro proceso hijo con fork:0
Id. proceso hijo:5184
Dentro proceso padre con fork:5184
Id proceso padre:5183
Id.
Fin del proceso padre
ajjaajj@armagnac :254:>

Diapo. No. 12
Sist. operativos. La concurrencia

Cdigo programa exph.c

#include<stdio.h>
main()
{

int i, n;

if ((n =fork()) = = -1)


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());
}

Diapo. No. 13
Sist. operativos. La concurrencia

Ejemplo ejecucin exph.c

ajjaajj@armagnac:140:>cc
jj jj@ g exph.c
p -o exph
p
ajjaajj@armagnac:141:>exph
Proceso hijo;id:2244
Proceso PADRE: id:2243
Cdigo ejecutado por:2243
Cdigo ejecutado por:2243
Cdigo ejecutado por:2243
ajjaajj@armagnac:142:>Cdigo ejecutado por:2244
Cdigo ejecutado por:2244
Cdigo ejecutado por:2244

ajjaajj@armagnac:142:>exph
Proceso hijo;id:2246
Cdigo ejecutado por:2246
Cdigo ejecutado por:2246
Cdi ejecutado
Cdigo j d por:2246
2246
Proceso PADRE: id:2245
Cdigo ejecutado por:2245
Cdigo ejecutado por:2245
Cdigo ejecutado por:2245
ajjaajj@armagnac:143:>exph
Proceso PADRE:id:2249
Proceso hijo: id:2250
Cdigo ejecutado por:2249
Cdigo ejecutado por:2249
Cdigo ejecutado por:2249
ajjaajj@armagnac:144:>

Diapo. No. 14
Sist. operativos. La concurrencia

Ejemplo ejecucin exph.c:


(continuacin)

ajjaajj@armagnac:144:>Cdigo ejecutado por:2250


Cdigo ejecutado por:2250
Cdigo ejecutado por:2250
ajjaajj@armagnac:144:>exph
jj jj@ g p
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
ajjaajj@armagnac:145:>exph
Proceso hijo;id:2269
Cdigo ejecutado por:2269
Cdigo ejecutado por:2269
Cdigo ejecutado por:2269
Proceso PADRE;id:2268
Cdi ejecutado
Cdigo j d por:2268
2268
Cdigo ejecutado por:2268
Cdigo ejecutado por:2268
ajjaajj@armagnac:146:>

Diapo. No. 15
Sist. operativos. La concurrencia

Cdigo programa padhijo7.c

#include<stdio.h>

main()
{
int i,m,n;

if ((n=fork()) = = -1) {
fprintf(stderr Error
fprintf(stderr, Error en la creacin de procesos \n
\n);
);
exit (1);
}
else
if (n = =0) /* Es el hijo */
f (i=0;i<7;
for (i 0 i 7 i++){
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);
}
}

Diapo. No. 16
Sist. operativos. La concurrencia

Ejemplo ejecucin padhijo.c


(1/3)

ajjaajj@armagnac:26:>cc padhijo7.c -o padhijo7


ajjaajj@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
ajjaajj@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,
1923 valor
alor i:5
Proceso HIJO con id: 1923, valor i:6

ajjaajj@armagnac:28:>

Diapo. No. 17
Sist. operativos. La concurrencia

Ejemplo ejecucin padhijo7.c


(2/3)

ajjaajj@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
ajjaajj@armagnac:29:>Proceso HIJO con id: 1929, valor i:0
Proceso HIJO con id: 1929, valor i:1
Proceso HIJO con id: 1929,
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
ajjaajj@armagnac:30:>

Diapo. No. 18
Sist. operativos. La concurrencia

Ejemplo ejecucin padhijo.c


(3/3)

ajjaajj@armagnac:29:>
jj jj@ 29 padhijo7
dhij 7
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,
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
ajjaajj@armagnac:30:>

Diapo. No. 19
Sist. operativos. La concurrencia

Llamada sistema wait()

Espera que un proceso hijo termine.

Sintaxis:
Si t i
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.

Diapo. No. 20
Sist. operativos. La concurrencia

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();
ait();
printf(Ya termino el hijo \n);
}
}

Diapo. No. 21
Sist. operativos. La concurrencia

Ejemplo ejecucin exwait1.c


ajjaajj@armagnac:224:>exwait1
Hijo
Padre
Ya termino el hijo.
ajjaajj@armagnac:225:>exwait1
Hijo
Hij
Padre
Ya termino el hijo
ajjaajj@armagnac:226:>exwait1
hijo
padre
Ya termino el hijo
romomez@armagnac:227>exwait1
Padre
Hijo
Ya termino el hijo
ajjaajj@armagnac:228:>exwait1
Padre
Hijo
Ya termino el hijo
ajjaajj@armagnac:229:>exwait1
Hijo
Padre
Ya termino el hijo
ajjaajj@armagnac:230:>:
Diapo. No. 22
Sist. operativos. La concurrencia

Cdigo programa exwait2.c

main()
{
int n,i;

if ((n=fork())==-1){
printf(Error
i f(E en ell fork()
f k() \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
i tf(P b del d l wait:
it DESPUES del
d l for
f \n);
\ )
}
}

Diapo. No. 23
Sist. operativos. La concurrencia

Ejemplo ejecucin exwait2.c, (en pos1)

ajjaajj@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
j 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
id:483, valor i:4
PADRE id:483, valor i:5
Prueba del wait: DESPUES del for
ajjaajj@armagnac:40:>exwait2
hijo id:486, valor de i:1
P b ddell wait:
Prueba it ANTES deld l for
f
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
ajjaajj @armagnac:41: >

Diapo. No. 24
Sist. operativos. La concurrencia

Ejemplo ejecucin exwait2.c, (en pos 1)


(continuacin)

ajjaajj @armagnac:41: >exwait2


hijo id: 488, valor de i:1
hijo id: 488,
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
A id
id:487,
48 valor
l ded i:1
i1
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
ajjaajj @armagnac:42:>

Diapo. No. 25
Sist. operativos. La concurrencia

Ejemplo ejecucin exwait2.c, (en pos2)

ajjaajj @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
j 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
ajjaajj @armagnac:133: >exwait2
hijo id:527,
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 id: 526
526, valor
l i:4
i4
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
ajjaajj @armagnac:134>

Diapo. No. 26
Sist. operativos. La concurrencia

Ejemplo ejecucin exwait2.c, (en pos2)


(continuacin)

ajjaajj @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: 528528, 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
P b ddell wait:
Prueba i DESPUES ddell ffor
ajjaajj @armagnac:135: >

Diapo. No. 27
Sist. operativos. La concurrencia

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 seall SIGCHLD es enviada


i d all padre.
d

- 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.
hijo

- Si no est activa la bandera SA_NOCLWAIT:


+ El proceso se vuelve zombie hasta que el padre
ejecuta uun wa
wait()
t() o waitpid()
wa tp d()
+ Si el padre ejecuta un wait() o waitpid() el estado de
terminacin est disponible para el padre

Diapo. No. 28
Sist. operativos. La concurrencia

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.

Diapo. No. 29
Sist. operativos. La concurrencia

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.

Diapo. No. 30
Sist. operativos. La concurrencia

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
toto c -o
o toto
$toto
Proceso hijo id: 9227
Fin del proceso 9227 valor regreso: 768
$

76810= 00000011000000002

Diapo. No. 31
Sist. operativos. La concurrencia

Ejemplo Terminacin Anormal


Cdigo cachafas
cachafas.c:
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
Id.
$kill -9 9286
Fin del proceso 9286 valor regreso: 9
$cachafas &
Id pproceso hijo
j id: 9290
$kill -5 9290
Fin del proceso 9290 valor regreso: 133
(se crea un core)
Diapo. No. 32
Sist. operativos. La concurrencia

La llamada waitpid()

E
Espera a que ell proceso hijo
hij cambie
bi de
d estado.
t d

Sintaxis:
#include <sys/types.h>
#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *stat_loc, int options);

Descripcin:
Suspende
p la ejecucin
j del proceso
p hasta que
q 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 -11 .- Se pide el estatus de cualquier hijo.


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.
Diapo. No. 33
Sist. operativos. La concurrencia

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.

Diapo. No. 34
Sist. operativos. La concurrencia

Ejemplo de uso de waitpid()

// Dado tres procesos hijos, espera que el segundo termine


main( )
{
int uno, dos, tres; /*identificadores procesos creados */
i retval;
int l /* valor
l de
d regreso de
d la
l llamada
ll d waitpid()
d() */
int *status; /* valor status terminacion proceso hijo */
int tmp; /* 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);
( d ()%10)
printf(\t\t Proceso tres (%d) a dormir %d sgs \n, getpid(), tmp);
sleep(tmp);
printf(\t\t Proceso tres termino \n);
} Diapo. No. 35
Sist. operativos. La concurrencia

else { /* Codigo proceso padre */


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

Diapo. No. 36
Sist. operativos. La concurrencia

Ejemplo ejecucin

ajjaajj@armagnac:330>cc exwaitpid.c -o corre


ajjaajj@armagnac:331>corre
Proceso uno (4292) a dormir 3 segs.
Proceso dos (4293) a dormir 3 segs.
Proceso tres (4294) a dormir 3 segs.
segs
Esperando que el proceso dos termine
Proceso uno termino
Proceso dos termino
Proceso dos (4293) termino con estatus: 256
ajjaajj@armagnac:332> Proceso tres termino
ajjaajj@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
ajjaajj@armagnac:333> Proceso tres termino
ajjaajj@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
ajjaajj@armagnac:334> Proceso tres termino
Proceso uno termino
ajjaajj@armagnac:334>

Diapo. No. 37
Sist. operativos. La concurrencia

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:
p

Proceso pierde el contexto que tena asociado con el


antiguo programa.

Proceso no pierde
i d sii pid,
id nii ell de
d su padre,
d y continua
i
con su papel de hijo.

Lo nico que retiene el proceso de su contexto son


los descriptores de archivos abiertos.
abiertos

Existen seis versiones de exec() que varan segn:

1.. Especificacin
spec cac programa
p og a a a ejecutar
ejecuta
2. Ambiente ejecucin
3. Paso de argumentos

Diapo. No. 38
Sist. operativos. La concurrencia

Arbol decisin para la llamada exec()

Ruta de acceso, (pathname)


del ejecutable.
j

Relativa
Absoluta

Ambiente? Ambiente?

Heredada N
Nueva
Nueva Heredada

Argumentos?
g Argumentos?
g Inexistente Argumentos?
g
Lista Vector Lista Vector Lista Vector
explcita Arreglo explcita Arreglo explcita Arreglo

execl() execv() execle() execve() execlp() execvp()

Diapo. No. 39
Sist. operativos. La concurrencia

Declaracin de Familias exec()

int execl(path, arg0, arg1, ...., argn, (char)*0)


char*path
char path, *arg0
arg0, *arg1
arg1, ...., *argn
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
h **path,
h **argv[], **envp[]

int execlp (file, arg0, arg1, ..., argn, (char)*0)


char *file, *arg0, *arg1, ..., *argn

int execvp (file, argv)


char *file, *argv[]

eenvp
vp - Arreglo
eg o de apuntadores
apu tado es a ca
caracteres
acte es que co
constituyen
st tuye el
e
ambiente en el que se va ejecutar el nuevo programa.
Termina con un apuntador a NULL.

Diapo. No. 40
Sist. operativos. La concurrencia

Parmetros del main

main (argc, argv, envp)

Nmero de Argumentos del Variables


argumentos command line de ambiente

HOME:
HOME
/home/dic/ajjaajj
3 grep
DISPLAY: egarac:0.0
benito
SHELL: /usr/bin/sh
directorio
HOST: armagnac

Diapo. No. 41
Sist. operativos. La concurrencia

Ejemplo: execlp

Se desea ejecutar sort con argumentos -n y foo


La llamada sera:

Argumentos

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

Nombre del Primer argumento Marca del fin


comando (argv[0]) de la lista

Diapo. No. 42
Sist. operativos. La concurrencia

Primer ejemplo uso llamada exec()

// 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);
e eclp(cmd[i] cmd[i],
execlp(cmd[i], cmd[i] 0);
printf(No se encontr el comando seleccionado \n);
}

Diapo. No. 43
Sist. operativos. La concurrencia

Segundo ejemplo uso llamada exec()


//Crea proceso que ejecuta comando pasado como argumento de comando lnea
#include
#i l d <sys/types.h>
< /t h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>

main(int argc, char *argv[])


{
int estatus;
ppid_t idhijo,j , 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);
it(1)
}
}
else
while ( idhijo != (waitreturn = waitpid (-1, &status, WNOHANG)))
if ( !((waitreturn == -1) && (errno != EINTR)) )
break;
exit(0);
}
Diapo. No. 44

You might also like