8x1 - Escuela Superior de Informática - Universidad de Castilla

Anuncio
Programación Concurrente y
Tiempo Real
Laboratorio
Sesión 2. Gestión de procesos
Escuela Superior de Informática
Universidad de Castilla-La Mancha
Curso 2011/2012
Grado en Ing. Informática
Primitivas básicas | Ejemplo paso a paso | Biblio
Sesión 2. Gestión de procesos
Identificando procesos
ID proceso
1. Primitivas básicas
2. Un ejemplo paso a paso
3. Bibliografía
#include <sys/types.h>
#include <unistd.h>
pid_t getpid (void); // ID del proceso
pid_t getppid (void); // ID del proceso padre
ID usuario
#include <sys/types.h>
#include <unistd.h>
uid_t getuid (void); // ID del usuario
uid_t geteuid (void); // ID del usuario efectivo
Curso 2011/2012
Grado en Ing. Informática
Curso 2011/2012
Primitivas básicas | Ejemplo paso a paso | Biblio
Creación de procesos :: fork() + exec()
proceso_A
Trp 3 de 23
Primitivas básicas | Ejemplo paso a paso | Biblio
Creación de procesos :: fork() + exec()
fork()
#include <sys/types.h>
#include <unistd.h>
fork()
pid_t fork (void); // 0 al hijo; ID del hijo al padre
proceso_A
(cont.)
proceso_B
(hijo)
execl()
SIGCHLD
wait()
Curso 2011/2012
Limpieza
tabla proc
exit()
zombie
Trp 4 de 23
Curso 2011/2012
Trp 5 de 23
Primitivas básicas | Ejemplo paso a paso | Biblio
Creación de procesos :: fork() + exec()
Primitivas básicas | Ejemplo paso a paso | Biblio
Espera y tratamiento de señales
Primitivas básicas
Primitivas básicas
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int execl (const char *path, const char *arg, ...);
int execlp (const char *file, const char *arg, ...);
int execle (const char *path, const char *arg, ...,
char *const envp[]);
int execv (const char *path, char *const argv[]);
int execvp (const char *file, char *const argv[]);
int execve (const char *path, char *const argv[],
char *const envp[]);
Curso 2011/2012
Trp 6 de 23
pid_t wait (int *status);
pid_t waitpid (pid_t pid, int *status, int options);
// BSD style
pid_t wait3 (int *status, int options,
struct rusage *rusage);
pid_t wait4 (pid_t pid, int *status, int options,
struct rusage *rusage);
Curso 2011/2012
Trp 7 de 23
Primitivas básicas | Ejemplo paso a paso | Biblio
Espera y tratamiento de señales
Primitivas básicas | Ejemplo paso a paso | Biblio
Problemática
archivo
Primitivas básicas
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal (int signum,
sighandler_t handler);
sumador1
restador1
sumador2
restador2
...
...
sumadorn
restadorn
Condición de carrera
Curso 2011/2012
Trp 8 de 23
Curso 2011/2012
Primitivas básicas | Ejemplo paso a paso | Biblio
Problemática
cont++
r1 = cont
r1 = r1 + 1
cont = r1
cont-r2 = cont
r2 = r2 - 1
cont = r2
Primitivas básicas | Ejemplo paso a paso | Biblio
Modelo de gestión de procesos
[cont = 7]
De forma
concurrente...
p:
p:
c:
c:
p:
c:
r1 =
r1 =
r2 =
r2 =
cont
cont
cont
r1 + 1
cont
r2 + 1
= r1
= r2
[r1 =
[r1 =
[r2 =
[r2 =
[cont
[cont
7]
8]
7]
8]
= 8]
= 8]
manager.c
manager
recursos
sumadores
restadores
fichero
sumador.c
restador.c
[cont = 8] (cont != 7)
Condición de carrera
Curso 2011/2012
Trp 10 de 23
Curso 2011/2012
Primitivas básicas | Ejemplo paso a paso | Biblio
Lanzando sumadores...
Trp 11 de 23
Primitivas básicas | Ejemplo paso a paso | Biblio
Lanzando restadores...
manager.c
// Se lanzan los sumadores...
for (i = 0; i < P_SUMADORES; i++)
switch (pid_hijo = fork()) {
case 0:
// Cada sumador recibe el nombre del archivo
// y el número de incrementos a realizar
execl("./exec/sumador", "sumador",
ARCHIVO, pNumOp, NULL);
break;
}
Curso 2011/2012
Trp 9 de 23
Trp 12 de 23
manager.c
// Se lanzan los restadores...
for (i = 0; i < P_RESTADORES; i++)
switch (pid_hijo = fork()) {
case 0:
// Cada restador recibe el nombre del archivo
// y el número de decrementos a realizar
execl("./exec/restador", "restador",
ARCHIVO, pNumOp, NULL);
break;
}
Curso 2011/2012
Trp 13 de 23
Primitivas básicas | Ejemplo paso a paso | Biblio
Pasando parámetros a un proceso
Primitivas básicas | Ejemplo paso a paso | Biblio
El proceso sumador
execl
sumador.c
#include <unistd.h>
#include
#include
#include
#include
int execl
(const char *path, const char *arg, ...);
<sys/types.h>
<unistd.h>
<stdlib.h>
<stdio.h>
Paso de parámetros
void sumador (const char *pFileName,
const char *pNumOP);
// Conversión de NUM_OPERACIONES a char*...
sprintf(pNumOp, "%d", NUM_OPERACIONES);
int main (int argc, char *argv[]) {
sumador(argv[1], argv[2]);
execl("./exec/sumador", "sumador",
ARCHIVO, pNumOp, NULL);
}
Curso 2011/2012
Trp 14 de 23
return 0;
Curso 2011/2012
Primitivas básicas | Ejemplo paso a paso | Biblio
El proceso sumador
Trp 15 de 23
Primitivas básicas | Ejemplo paso a paso | Biblio
Espera procesos hijo
sumador.c
manager.c
void sumador (const char *pFileName, const char *pNumOP) {
FILE *fp;
int i, valor, operaciones;
// Se espera la terminación de los procesos...
if (signal(SIGCHLD, esperar) == SIG_ERR) {
fprintf(stderr, "No se esperó a un proceso.\n");
exit(1);
}
printf("%d incrementando...\n", getpid());
operaciones = atoi(pNumOP);
for (i = 0; i < operaciones; i++)
fp = fopen(pFileName, "r");
fscanf(fp, "%d", &valor);
//
fclose(fp);
valor++;
//
fp = fopen(pFileName, "w");
fprintf(fp, "%d", valor);
//
fclose(fp);
}
void esperar (int senhal) {
int i;
while (wait3(&i, WNOHANG, NULL) > 0);
}
{
Lectura
Actualización
Escritura
}
Curso 2011/2012
Trp 16 de 23
Curso 2011/2012
Primitivas básicas | Ejemplo paso a paso | Biblio
Gestión de interrupciones
Trp 17 de 23
Primitivas básicas | Ejemplo paso a paso | Biblio
Gestión de interrupciones
manager.c
manager.c
// Manejo de Ctrol+C.
if (signal(SIGINT, controlador) == SIG_ERR) {
fprintf(stderr, "Terminación incorrecta.\n");
exit(1);
}
void controlador (int senhal) {
printf("\nCtrl+c capturada.\n");
// Liberación de recursos...
// Se muestra el contenido real del archivo...
int valor;
FILE *fp = fopen(ARCHIVO, "r");
fscanf(fp, "%d", &valor);
fclose(fp);
printf("Valor real: %d\n", valor);
while(1) // Bucle infinito de espera.
pause(); // A la espera de señales.
// Salida del programa.
exit(0);
}
Curso 2011/2012
Trp 18 de 23
Curso 2011/2012
Primitivas básicas | Ejemplo paso a paso | Biblio
Modelo de Makefile
Makefile
:=
:=
:=
:=
obj/
exec/
include/
src/
manager: $(DIROBJ)manager.o
$(CC) $(LDFLAGS) -o $(DIREXE)$@ $^
sumador: $(DIROBJ)sumador.o
$(CC) $(LDFLAGS) -o $(DIREXE)$@ $^
CFLAGS := -I$(DIRHEA) -c -Wall
LDFLAGS := -lrt
CC := gcc
restador: $(DIROBJ)restador.o
$(CC) $(LDFLAGS) -o $(DIREXE)$@ $^
all : dirs manager sumador restador
$(DIROBJ)%.o: $(DIRSRC)%.c
$(CC) $(CFLAGS) $^ -o $@
dirs:
mkdir -p $(DIROBJ) $(DIREXE)
Curso 2011/2012
Primitivas básicas | Ejemplo paso a paso | Biblio
Modelo de Makefile
Makefile
DIROBJ
DIREXE
DIRHEA
DIRSRC
Trp 19 de 23
clean :
rm -rf *~ core $(DIROBJ) $(DIREXE)
$(DIRHEA)*~ $(DIRSRC)*~
Trp 20 de 23
Curso 2011/2012
Trp 21 de 23
Primitivas básicas | Ejemplo paso a paso | Biblio
Ejecución
Bibliografía
manager.c
Valor inicial: 7
Valor esperado: 7
8967 incrementando...
8970 decrementando...
8968 decrementando...
8965 incrementando...
8966 incrementando...
8969 decrementando...
^C
Ctrl+c capturada.
Finalizando...
Primitivas básicas | Ejemplo paso a paso | Biblio
#define
#define
#define
#define
#define
ARCHIVO "./test.txt"
VALOR_INICIAL 7
P_SUMADORES 3
P_RESTADORES 3
NUM_OPERACIONES 3
●
●
Robbins, K.A., Robbins, S.,
Unix Programación Práctica,
Sec. 2.3-2.7
Rochkind, M.J.,
Advanced Unix Programming,
Sec. 5.3, 5.5, 5.7, 5.8, 5.9
Valor real: 3
OK!
Curso 2011/2012
Trp 22 de 23
Curso 2011/2012
Trp 23 de 23
Descargar