+ All Categories
Home > Documents > Cs Posix Ssoo2

Cs Posix Ssoo2

Date post: 11-Feb-2018
Category:
Upload: david-gonzalez-arjona
View: 234 times
Download: 0 times
Share this document with a friend

of 79

Transcript
  • 7/23/2019 Cs Posix Ssoo2

    1/79

    Comunicacin ysincronizacin entre procesos

    Mara de los Santos PrezHernndez

    [email protected]

  • 7/23/2019 Cs Posix Ssoo2

    2/79

    ndice Procesos concurrentes. El problema de la seccin crtica. Problemas clsicos de comunicacin y

    sincronizacin. Mecanismos de comunicacin y

    sincronizacin. Interbloqueos.

  • 7/23/2019 Cs Posix Ssoo2

    3/79

    Referencias bibliogrficas Sistemas Operativos: una visin aplicada Jess Carretero et al.

    McGraw Hill, 2001 Sistemas Operativos Willian Stalling Willian Stalling Prentice Hall, 1997

    Operating System Concepts A. Silberschatz, P. Galvin Addison-Wesley, 1998

  • 7/23/2019 Cs Posix Ssoo2

    4/79

    Procesos concurrentes (I) Modelos

    Multiprogramacin en un nico procesador Multiprocesador Multicomputador (proceso distribuido)

    Razones Compartir recursos fsicos Compartir recursos lgicos Acelerar los clculos Modularidad Comodidad

  • 7/23/2019 Cs Posix Ssoo2

    5/79

    Procesos concurrentes (II) Tipos de procesos

    Independientes

    Cooperantes Interaccin entre procesos

    Compiten por recursos Comparten recursos

  • 7/23/2019 Cs Posix Ssoo2

    6/79

    ro ema e a n eracc nentre procesos (procesos

    ligeros) Calcula la suma de los N primeros

    nmeros utilizando procesosligeros.

    int suma_total = 0; void suma_parcial(int ni, int nf) { int j = 0; int suma_parcial = 0;

    for (j = ni; j

  • 7/23/2019 Cs Posix Ssoo2

    7/79

    Ejemplo con seccin crtica

    (procesos ligeros) void suma_parcial(int ni, int nf) { int j = 0; int suma_parcial = 0;

    for (j = ni; j

  • 7/23/2019 Cs Posix Ssoo2

    8/79

    Problema de la interaccin

    entre procesos void ingresar(char *cuenta,

    int cantidad)

    {

    int saldo, fd;

    fd = open(cuenta, O_RDWR);

    read(fd,&saldo,sizeof(int));

    saldo = saldo + cantidad;

    lseek(fd, 0, SEEK_SET);

    write(fd,&saldo,sizeof(int));

    close(fd);

    return;

    }

    Si dos procesosejecutanconcurrentement

    e este cdigo sepuede perderalgn ingreso.

    Solucin:secciones

    crticas

  • 7/23/2019 Cs Posix Ssoo2

    9/79

    Ejemplo con seccin crtica void ingresar(char *cuenta, int cantidad) { int saldo, fd;

    fd = open(cuenta, O_RDWR);

    Entrada en la seccin crticaread(fd, &saldo, sizeof(int));

    saldo = saldo + cantidad; lseek(fd, 0, SEEK_SET); write(fd, &saldo, sizeof(int)); Salida de la seccin crtica

    close(fd); return; }

    Requisitos paraofrecerseccionescrticas:

    Exclusin mutua Progreso

    Espera limitada

  • 7/23/2019 Cs Posix Ssoo2

    10/79

    Mecanismos de comunicacin Ficheros Pipes FIFOS Variables en memoria compartida Paso de mensajes

    Sockets

  • 7/23/2019 Cs Posix Ssoo2

    11/79

    Mecanismos de

    Sincronizacin Construcciones de los lenguajes concurrentes

    (procesos ligeros) Servicios del sistema operativo:

    Seales (asincronismo) Pipes FIFOS Semforos Mutex y variables condicionales Paso de mensajes

    Las operaciones de sincronizacin deben seratmicas

  • 7/23/2019 Cs Posix Ssoo2

    12/79

    arac er s cas e osmecanismos de

    comunicacin Identificacin

    Mecanismos de

    nombrado Sin nombre Con nombre local Con nombre de

    red

    Identificador interno Identificadorpropio

    Descriptor defichero

    Flujo de datos Unidireccional

    Bidireccional Buffering

    Sin buffering Con buffering

    Sincronizacin Sncrono(bloqueante)

    Asncrono (nobloqueante)

  • 7/23/2019 Cs Posix Ssoo2

    13/79

    ro emas c s cos ecomunicacin y

    sincronizacin

    P r o c e s oP r o d u c t o r

    P r o c e s oC o n s u m i d o r

    M e c a n i s m o d ec o m u n i c a c i n

    F l u j o d ed a t o s

    E s c r i t o r L e c t o r L e c t o r E s c r i t o r L e c t o r

    R e c u r s o

  • 7/23/2019 Cs Posix Ssoo2

    14/79

    Problemas clsicos decomunicacin y sincronizacin

    (II)

    Computad

    ora

    Computad

    ora

    Procesoclien

    te

    S.O.

    Peticin

    Respuesta

    Procesoservid

    or

  • 7/23/2019 Cs Posix Ssoo2

    15/79

    Pipes Mecanismo de comunicacin y

    sincronizacin sin nombre Slo puede utilizarse entre los

    procesos hijos del proceso quecre el pipe int pipe(int fildes[2]);

    Identificacin: dos descriptoresde fichero

    Flujo de datos: unidireccional Con buffering

    read(fildes[0],buffer,n) Pipe vaco se bloquea

    el lector Pipe conp bytes

    Si p n devuelve n Si p n devuelve p

    Si pipe vaco y no hayescritores devuelve 0

    write(fildes[1], buffer,n)

    Pipe lleno se bloqueael escritor

    Si no hay lectores serecibe la sealSIGPIPE

    Lecturas y escrituras

    atmicas (cuidado contamaos randes)

  • 7/23/2019 Cs Posix Ssoo2

    16/79

    Secciones crticas con pipes void main(void) { int fildes[2]; /* pipe sincronizacin

    */ char c; /* carcter sincronizacin */

    pipe(fildes); write(fildes[1], &c, 1); /* necesario para entrar en la seccion crtica la primera vez */

    if (fork() == 0) { /* proceso hijo */

    for(;;) { read(fildes[0], &c, 1); /* entrada seccin crtica */ /* seccin crtica */ write(fildes[1], &c, 1); /* salida seccion crtica */

    } }

    else /* proceso padre */

    {

    for(;;)

    {

    read(fildes[0], &c, 1);/* entrada seccin

    crtica*/

    /* seccin crtica */

    write(fildes[1], &c, 1);/* salida seccin crtica

    */

    }

    } }

  • 7/23/2019 Cs Posix Ssoo2

    17/79

    Productor-consumidor conpipes

    void main(void) { int fildes[2]; /* pipe para comunicar

    y sincronizar */ int dato_p[4]; /* datos a producir */

    int dato_c; /* dato a consumir */

    pipe(fildes);

    if (fork() == 0) /* productor */ { for(;;)

    { /* producir dato_p */ write(fildes[1], dato_p, 4*sizeof(int)); } }

    else /* consumidor */

    {

    for(;;)

    {

    read(fildes[0],&dato_c,

    sizeof(int));

    /* consumir dato */

    }

    }

    }

    Proceso

    hijo

    Proceso

    padre

    pipe

    SO

    write read

    Flujo dedatos

  • 7/23/2019 Cs Posix Ssoo2

    18/79

    Ejecucin de mandatos conpipes

    /* programa que ejecuta el mandato ls | wc*/

    void main(void) {

    int fd[2]; pid_t pid;

    if (pipe(fd) < 0) { perror(``pipe''); exit(1);

    }

    pid = fork(); switch(pid) {

    case -1: /* error */ perror(``fork''); exit(1); case 0: /* proceso hijo ejecuta ls

    */

    close(fd[0]); /* cierra el pipe delectura */

    close(STDOUT_FILENO); /* cierra lasalida estandar */

    dup(fd[1]); close(fd[1]);

    execlp(``ls'',``ls'',NULL); perror(``execlp''); exit(1); default: /* proceso padre ejecuta wc

    */ close(fd[1]); /* cierra el pipe de

    escritura */ close(STDIN_FILENO); /* cierra la

    entrada estandar */

    dup(fd[0]); close(fd[0]); execlp(``wc'',``wc'',NULL); perror(``execlp''); } }

  • 7/23/2019 Cs Posix Ssoo2

    19/79

    Ejecucin de mandatos conpipes (II)

    P r o c e s o

    S T D I NS T D O U T

    p i p e ( f d )

    f o r k ( )

    P r o c e s o

    S T D I NS T D O U T

    f d [ 0 ]f d [ 1 ]

    p i p e

    r e d i r e c c i n

    P r o c e s o h i j o

    S T D I NS T D O U Tf d [ 0 ]f d [ 1 ]

    P r o c e s o

    S T D I NS T D O U Tf d [ 0 ]f d [ 1 ]

    p i p e

    e x e c

    P r o c e s o h i jo

    S T D I N

    S T D O U T

    P r o c e s o

    S T D I N

    S T D O U Tp i p e

    P r o c e s o h i jo

    S T D I N

    S T D O U T

    P r o c e s o

    l s w c

    S T D I N

    S T D O U Tp i p e

  • 7/23/2019 Cs Posix Ssoo2

    20/79

    FIFOS

    Igual que los pipes Mecanismo de comunicacin y

    sincronizacin con nombre Misma mquina

    Servicios

    mkfifo(char *name,mode_t mode); Crea un FIFO con nombre

    name

    open(char *name, intflag);

    Abre un FIFO (paralectura, escritura o

    ambas) Bloquea hasta quehaya algn procesoen el otro extremo

    Lectura y escritura medianteread() y write()

    Igual semntica que lospipes Cierre de un FIFO mediante

    close() Borrado de un FIFO mediante

    unlink()

  • 7/23/2019 Cs Posix Ssoo2

    21/79

    Semforos Mecanismo de sincronizacin Misma mquina Objeto con un valor entero

    Dos operaciones atmicas s_espera(s) { s = s - 1; if (s < 0) Bloquear al proceso }

    s_abre(s) { s = s + 1; if (s

  • 7/23/2019 Cs Posix Ssoo2

    22/79

    Semforos POSIX sem_init(sem_t *sem, int shared, int val);

    Inicializa un semforo sin nombre int sem_destroy(sem_t *sem);

    Destruye un semforo sin nombre sem_t *sem_open(char *name,int flag,mode_t mode,int val);

    Abre (crea) un semforo con nombre. int sem_close(sem_t *sem);

    Cierra un semforo con nombre. int sem_unlink(char *name);

    Borra un semforo con nombre. int sem_wait(sem_t *sem);

    Realiza la operacin s_espera sobre un semforo. int sem_post(sem_t *sem);

    Realiza la operacin s_abre sobre un semforo.

    P d t id

  • 7/23/2019 Cs Posix Ssoo2

    23/79

    Productor-consumidor consemforos (buffer acotado ycircular)

    C o n s u m i d o r

    P r o d u c t o r

  • 7/23/2019 Cs Posix Ssoo2

    24/79

    Productor-consumidor consemforos (II)

    #define MAX_BUFFER 1024 #define DATOS_A_PRODUCIR 100000 sem_t elementos; /* elementos buffer

    */ sem_t huecos; /* huecos buffer */ sem_t mutex; /* controla excl.mutua

    */

    int buffer[MAX_BUFFER];/*buffercomn*/

    void main(void)

    { pthread_t th1, th2; /* id.

    threads*/ /* inicializar los semaforos */ sem_init(&elementos, 0, 0); sem_init(&huecos, 0, MAX_BUFFER); sem_init(&mutex, 0, 1);

    /* crear los procesosligeros */

    pthread_create(&th1,NULL, Productor, NULL);

    pthread_create(&th2,NULL, Consumidor, NULL);

    /* esperar sufinalizacion */

    pthread_join(th1, NULL); pthread_join(th2, NULL);

    sem_destroy(&huecos); sem_destroy(&elementos); sem_destroy(&mutex);

    exit(0); }

  • 7/23/2019 Cs Posix Ssoo2

    25/79

    Productor-consumidor consemforos (III) void Productor(void) /* cdigo del productor */ { int pos = 0; /* posicin dentro del buffer */ int dato; /* dato a producir */

    int i;

    for(i=0; i < DATOS_A_PRODUCIR; i++ ) { dato = i; /* producir dato */ sem_wait(&huecos); /* un hueco menos */ sem_wait(&mutex); /* entra en la seccin crtica */ buffer[pos] = dato; pos = (pos + 1) % MAX_BUFFER; sem_post(&mutex); /* deja la seccin crtica */ sem_post(&elementos); /* un elemento ms */ } pthread_exit(0); }

  • 7/23/2019 Cs Posix Ssoo2

    26/79

    Productor-consumidor consemforos (IV) void Consumidor(void) /* cdigo del Consumidor */ { int pos = 0; int dato;

    int i;

    for(i=0; i < DATOS_A_PRODUCIR; i++ ) { sem_wait(&elementos); /* un elemento menos */ sem_wait(&mutex); /* entra en la seccin crtica */ dato = buffer[pos]; pos = (pos + 1) % MAX_BUFFER; sem_post(&mutex); /* deja la seccin crtica */ sem_post(&huecos); /* un hueco ms */ /* consumir dato */ } pthread_exit(0); }

  • 7/23/2019 Cs Posix Ssoo2

    27/79

    Lectores-escritores consemforos

    int dato = 5; /* recurso */ int n_lectores = 0;/* num. Lectores

    */ sem_t sem_lec; /* acceso n_lectores

    */ sem_t mutex; /* acceso a dato */

    void main(void) { pthread_t th1, th2, th3, th4;

    sem_init(&mutex, 0, 1); sem_init(&sem_lec, 0, 1);

    pthread_create(&th1, NULL,Lector, NULL);

    pthread_create(&th2, NULL,Escritor, NULL);

    pthread_create(&th3, NULL,Lector, NULL);

    pthread_create(&th4, NULL,Escritor, NULL);

    pthread_join(th1, NULL); pthread_join(th2, NULL); pthread_join(th3, NULL); pthread_join(th4, NULL);

    /*cerrar todos los

    semaforos*/ sem_destroy(&mutex); sem_destroy(&sem_lec);

    exit(0); }

  • 7/23/2019 Cs Posix Ssoo2

    28/79

    Lectores-escritores consemforos (II) void Lector(void) /* cdigo del lector */ { sem_wait(&sem_lec); n_lectores = n_lectores + 1; if (n_lectores == 1)

    sem_wait(&mutex); sem_post(&sem_lec);

    printf(``%d\n'', dato); /* leer dato */

    sem_wait(&sem_lec);

    n_lectores = n_lectores - 1; if (n_lectores == 0) sem_post(&mutex); sem_post(&sem_lec);

    pthread_exit(0);

    }

  • 7/23/2019 Cs Posix Ssoo2

    29/79

    Lectores-escritores consemforos (III)

    void Escritor(void) /* cdigo del escritor */

    {

    sem_wait(&mutex);

    dato = dato + 2; /* modificar el recurso */

    sem_post(&mutex);

    pthread_exit(0);

    }

  • 7/23/2019 Cs Posix Ssoo2

    30/79

    Objetos de memoriacompartida

    Permiten crear unsegmento dememoria

    compartido entreprocesos de lamisma mquina.

    Declaracin

    independiente devariables

    D a t o s

    T e x t o

    P r o c e s o A P r o c e s o B

    P i l a

    T e x t o

    D a t o s

    P i l aS e g m e n t od e m e m o r i ac o m p a r t i d a

    v a r 1

    * v a r 1 = 2

    2

    v a r 2

  • 7/23/2019 Cs Posix Ssoo2

    31/79

    Servicios int shm_open(char *name, int oflag, mode_t mode);

    Crea un objeto de memoria a compartir entre procesos int shm_open (char *name, int oflag);

    Slo apertura int close(int fd);

    Cierre. El objeto persiste hasta que es cerrado por el ltimoproceso.

    int shm_unlink(const char *name); Borra una zona de memoria compartida.

    void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);

    Establece una proyeccin entre el espacio de direcciones deun proceso y un descriptor de fichero u objeto dememoria compartida.

  • 7/23/2019 Cs Posix Ssoo2

    32/79

    Servicios (II) len especifica el nmero de bytes a proyectar. protel tipo de acceso (lectura, escritura o

    ejecucin). PROT_READ, PROT_WRITE, PROT_EXEC o

    PROT_NONE. flags especifica informacin sobre el manejo

    de los datos proyectados (compartidos,privado, etc.).

    MAP_SHARED, MAP_PRIVATE, ... fildes representa el descriptor de fichero del

    fichero o descriptor del objeto de memoria aproyectar.

    offdesplazamiento dentro del fichero a partirde cual se realiza la proyeccin.

    void munmap(void *addr, size_t len); Desproyecta parte del espacio de direcciones de

    un proceso comenzando en la direccin addr.El tamao de la regin a desproyectar es len.

    ro uc or consum or con

  • 7/23/2019 Cs Posix Ssoo2

    33/79

    ro uc or-consum or conobjetos de memoriacompartida

    Productor: Crea la zona de memoria compartida

    (shm_open) Le asigna espacio (ftruncate)

    int ftruncate (int fd, size_t len); Proyecta la zona de memoria compartida

    en su espacio

    de direcciones (mmap) Utiliza la zona de memoria compartida Desproyecta la zona de memoria

    compartida

    Cierra y borra el objeto de memoriacompartida

    Productor consumidor con

  • 7/23/2019 Cs Posix Ssoo2

    34/79

    Productor-consumidor conobjetos de memoria compartida(II)

    Consumidor: Debe esperar a que la zona de memoria

    compartida este creada Abre la zona de memoria compartida

    (shm_open) Proyecta la zona de memoria compartida

    en su espacio de direcciones (mmap) Utiliza la zona de memoria compartida Cierra el objeto de memoria compartida

  • 7/23/2019 Cs Posix Ssoo2

    35/79

    Cdigo del productor #define MAX_BUFFER 1024 /* tamao del buffer */ #define DATOS_A_PRODUCIR 100000 /* datos a producir */ sem_t *elementos; /* elementos en el buffer */ sem_t *huecos; /* huecos en el buffer */

    sem_t *mutex; /* acceso al buffer */

    void main(int argc, char *argv[]) { int shd; int *buffer; /* buffer comn */

    /* el productor crea el segmento de memoria compartida */ shd = shm_open("BUFFER", O_CREAT|O_WRONLY, 0700); ftruncate(shd, MAX_BUFFER * sizeof(int)); /* proyectar el objeto de memoria compartida en el espacio de direcciones del productor */

  • 7/23/2019 Cs Posix Ssoo2

    36/79

    Cdigo del productor (II)

    buffer = (int *) mmap(NULL, MAX_BUFFER * sizeof(int), PROT_WRITE, MAP_SHARED, shd, 0);

    /* El productor crea los semforos */

    elementos = sem_open("ELEMENTOS", O_CREAT, 0700, 0); huecos = sem_open("HUECOS", O_CREAT, 0700, MAX_BUFFER); mutex = sem_open("MUTEX", O_CREAT, 0700, 1); Productor(buffer);

    /* desproyectar el buffer compartido */

    munmap(buffer, MAX_BUFFER * sizeof(int)); close(shd); /* cerrar el objeto de memoria compartida */ shm_unlink("BUFFER"); /* borrar el objeto de memoria */

    sem_close(elementos); sem_close(huecos); sem_close(mutex); sem_unlink("ELEMENTOS"); sem_unlink("HUECOS");

    sem_unlink("MUTEX"); }

  • 7/23/2019 Cs Posix Ssoo2

    37/79

    Cdigo del productor (III) void Productor(int *buffer){ /* cdigo del productor */ int pos = 0; /* posicin dentro del buffer */ int dato; /* dato a producir */ int i;

    for(i=0; i < DATOS_A_PRODUCIR; i++ ) { dato = i; /* producir dato */ sem_wait(huecos); /* un hueco menos */ sem_wait(mutex);

    buffer[pos] = dato; pos = (pos + 1) % MAX_BUFFER; sem_post(mutex); sem_post(elementos); /* un elemento ms */ } return;

    }

  • 7/23/2019 Cs Posix Ssoo2

    38/79

    Cdigo del consumidor #define MAX_BUFFER 1024 /* tamao del buffer */ #define DATOS_A_PRODUCIR 100000 /* datos a producir */

    sem_t *elementos; /* elementos en el buffer */

    sem_t *huecos; /* huecos en el buffer */ sem_t *mutex; /* acceso al buffer */ void main(int argc, char *argv[]) { int shd; int *buffer; /* buffer comn */

    /* el consumidor abre el segmento de memoria compartida */ shd = shm_open("BUFFER", O_RDONLY);

    /* proyectar el objeto de memoria compartida en el espacio de direcciones del productor */

  • 7/23/2019 Cs Posix Ssoo2

    39/79

    Cdigo del consumidor (II) buffer = (int *) mmap(NULL, MAX_BUFFER * sizeof(int), PROT_READ, MAP_SHARED, shd, 0);

    /* El consumidor abre los semforos */ elementos = sem_open("ELEMENTOS", 0); huecos = sem_open("HUECOS", 0); mutex = sem_open("MUTEX", 0); Consumidor(buffer);

    /* desproyectar el buffer compartido */ munmap(buffer, MAX_BUFFER * sizeof(int)); close(shd); /* cerrar el objeto de memoria compartida */

    /* cerrar los semforos */ sem_close(elementos); sem_close(huecos); sem_close(mutex); }

  • 7/23/2019 Cs Posix Ssoo2

    40/79

    Cdigo del consumidor (III) void Consumidor(char *buffer) /*cdigo del Consumidor*/ { int pos = 0; int i, dato;

    for(i=0; i < DATOS_A_PRODUCIR; i++ ) { sem_wait(elementos); /* un elemento menos */ sem_wait(mutex); dato = buffer[pos]; pos = (pos + 1) % MAX_BUFFER; sem_post(mutex); sem_post(huecos); /* un hueco mas */ printf("Consume %d \n", dato); /* consumir dato */ } return;

    }

  • 7/23/2019 Cs Posix Ssoo2

    41/79

    Mutex y variablescondicionales

    Un mutex es un mecanismo desincronizacin indicado para procesosligeros.

    Es un semforo binario con dosoperaciones atmicas: lock(m): Intenta bloquear el mutex; si el

    mutex ya est bloqueado el proceso sesuspende. unlock(m): Desbloquea el mutex; si

    existen procesos bloqueados en elmutex se desbloquea a uno.

  • 7/23/2019 Cs Posix Ssoo2

    42/79

    Secciones crticas con mutex lock(m); /* entrada en la seccin crtica */

    /* seccin crtica */

    unlock(s); /* salida de la seccin crtica */

    La operacin unlockdebe realizarla el proceso ligero queejecut lock P r o c e s o

    l i g e r o A

    l o c k m u t e x

    S e c c i nc r t i c a

    P r o c e s ol i g e r o B

    l o c k m u t e x

    u n l o c k m u t e x o b t ie n e m u t e x

    P r o c e s o l i g e r o e j e c u t a n d o

    P r o c e s o l i g e r o b l o q u e a d o

    P u n t o d e s i n c r o n i z a c i n

  • 7/23/2019 Cs Posix Ssoo2

    43/79

    Variables condicionales Variables de sincronizacin

    asociadas a un mutex Conveniente ejecutarlas

    entre locky unlock. Dos operaciones atmicas:

    wait: Bloquea alproceso ligero que laejecuta y le expulsadel mutex

    signal: Desbloquea a

    uno o variosprocesossuspendidos en lavariable condicional.El proceso que sedespierta compitede nuevo por el

    mutex

    P r o c e s ol i g e r o B

    P r o c e s ol i g e r o A

    w a i t

    u n l o c k m u t e x

    A d q u i e r e e l m u t e x

    A d q u i e r e e l m u t e x

    S e c o m p i t e p o r e l m u t e x

    l o c kl o c k

    u n l o c k

    P r o c e s o l i g e r o b l o q u e a d o e s p e r a n d o s i g n a l

    P r o c e s o l i g e r o b l o q u e a d o e s p e r a n d o u n l o c k

    s i g n a l

  • 7/23/2019 Cs Posix Ssoo2

    44/79

    Uso de mutex y variablescondicionales

    Proceso ligero A:

    lock(mutex); /* acceso al

    recurso */ /* codigo de la seccin crtica */ while (condicion == FALSE)

    wait(condition, mutex); /* resto de la seccin

    crtica */ unlock(mutex);

    Proceso ligero B

    lock(mutex); /* acceso alrecurso

    */ /* cdigo de la seccin

    crtica */ /* se modifica la

    condiccin y sta sehace TRUE */

    condicion = true; signal(condition, mutex); unlock(mutex);

    Importante utilizar

    while

  • 7/23/2019 Cs Posix Ssoo2

    45/79

    Servicios int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr)

    Inicializa un mutex. int pthread_mutex_destroy(pthread_mutex_t *mutex);

    Destruye un mutex. int pthread_mutex_lock(pthread_mutex_t *mutex);

    Intenta obtener el mutex. Bloquea al proceso ligero si elmutexse encuentra adquirido por otro proceso ligero.

    int pthread_mutex_unlock(pthread_mutex_t *mutex); Desbloquea el mutex.

    int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr);

    Inicializa una variable condicional. int pthread_cond_destroy(pthread_cond_t *cond);

    Destruye una variable condicional.

  • 7/23/2019 Cs Posix Ssoo2

    46/79

    Servicios (II) int pthread_cond_signal(pthread_cond_t *cond);

    Se reactivan uno o ms de los procesos ligeros que estnsuspendidos en la variable condicional cond.

    No tiene efecto si no hay ningn proceso ligero esperando

    (diferente a los semforos). int pthread_cond_broadcast(pthread_cond_t *cond);

    Todos los threads suspendidos en la variable condicionalcond se reactivan.

    No tiene efecto si no hay ningn proceso ligero esperando. int pthread_cond_wait(pthread_cond_t *cond,

    pthread_mutex_t *mutex); Suspende al proceso ligero hasta que otro proceso sealiza la

    variable condicional cond. Automticamente se libera el mutex. Cuando se despierta el

    proceso ligero vuelve a competir por el mutex.

  • 7/23/2019 Cs Posix Ssoo2

    47/79

    Productor-consumidor conmutex

    #define MAX_BUFFER 1024 /* tamao del buffer */ #define DATOS_A_PRODUCIR 100000 /* datos a producir */ pthread_mutex_t mutex; /* mutex para controlar el acceso al buffer compartido */

    pthread_cond_t no_lleno; /* llenado del buffer */ pthread_cond_t no_vacio; /* vaciado del buffer */ int n_elementos; /* elementos en el buffer */ int buffer[MAX_BUFFER]; /* buffer comn */

    main(int argc, char *argv[]) { pthread_t th1, th2;

    pthread_mutex_init(&mutex, NULL);

  • 7/23/2019 Cs Posix Ssoo2

    48/79

    Productor-consumidor conmutex (II)

    pthread_cond_init(&no_lleno, NULL);

    pthread_cond_init(&no_vacio, NULL);

    pthread_create(&th1, NULL, Productor, NULL);

    pthread_create(&th2, NULL, Consumidor, NULL);

    pthread_join(th1, NULL); pthread_join(th2, NULL);

    pthread_mutex_destroy(&mutex); pthread_cond_destroy(&no_lleno); pthread_cond_destroy(&no_vacio);

    exit(0); }

  • 7/23/2019 Cs Posix Ssoo2

    49/79

    Productor-consumidor conmutex (III)

    void Productor(void) { /* cdigo del productor */ int dato, i ,pos = 0; for(i=0; i < DATOS_A_PRODUCIR; i++ ) { dato = i; /* producir dato */

    pthread_mutex_lock(&mutex); /* acceder al buffer*/

    while (n_elementos==MAX_BUFFER)/* si buffer lleno*/

    pthread_cond_wait(&no_lleno, &mutex);/* bloqueo*/

    buffer[pos] = dato; pos = (pos + 1) % MAX_BUFFER; n_elementos ++; pthread_cond_signal(&no_vacio);/* buffer no vaco

    */ pthread_mutex_unlock(&mutex); }

  • 7/23/2019 Cs Posix Ssoo2

    50/79

    Productor-consumidor conmutex (IV)

    void Consumidor(void) { /* cdigo del consumidor */ int dato, i ,pos = 0; for(i=0; i < DATOS_A_PRODUCIR; i++ ) { pthread_mutex_lock(&mutex); /* acceder al buffer

    */ while (n_elementos == 0) /* si buffer vaco */ pthread_cond_wait(&no_vacio, &mutex);/* bloqueo

    */ dato = buffer[pos]; pos = (pos + 1) % MAX_BUFFER;

    n_elementos --; pthread_cond_signal(&no_lleno); /* buffer no lleno

    */ pthread_mutex_unlock(&mutex); printf("Consume %d \n", dato); /* consume dato */ } pthread_exit(0);

  • 7/23/2019 Cs Posix Ssoo2

    51/79

    Lectores-escritores conmutex

    int dato = 5; /* recurso */

    int n_lectores = 0; /* numero de lectores */

    pthread_mutex_t mutex; /* control del acceso a dato*/

    pthread_mutex_t mutex_lectores; /* control de n_lectores */

    main(int argc, char *argv[])

    {

    pthread_t th1, th2, th3, th4;

    pthread_mutex_init(&mutex, NULL);

    pthread_mutex_init(&mutex_lectores, NULL);

  • 7/23/2019 Cs Posix Ssoo2

    52/79

    Lectores-escritores conmutex (II)

    pthread_create(&th1, NULL, Lector, NULL); pthread_create(&th2, NULL, Escritor, NULL); pthread_create(&th3, NULL, Lector, NULL); pthread_create(&th4, NULL, Escritor, NULL);

    pthread_join(th1, NULL); pthread_join(th2, NULL); pthread_join(th3, NULL); pthread_join(th4, NULL);

    pthread_mutex_destroy(&mutex); pthread_mutex_destroy(&mutex_lectores);

    exit(0); }

  • 7/23/2019 Cs Posix Ssoo2

    53/79

    Lectores-escritores conmutex (III)

    void Lector(void) { /* cdigo del lector */ pthread_mutex_lock(&mutex_lectores); n_lectores++; if (n_lectores == 1)

    pthread_mutex_lock(&mutex); pthread_mutex_unlock(&mutex_lectores);

    printf("%d\n", dato); /* leer dato */

    pthread_mutex_lock(&mutex_lectores); n_lectores--; if (n_lectores == 0) pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex_lectores); pthread_exit(0);

    }

  • 7/23/2019 Cs Posix Ssoo2

    54/79

    Lectores-escritores conmutex (IV) void Escritor(void) /* cdigo del escritor

    */

    {

    pthread_mutex_lock(&mutex);

    dato = dato + 2; /* modificar el recurso*/

    pthread_mutex_unlock(&mutex);

    pthread_exit(0);

    }

  • 7/23/2019 Cs Posix Ssoo2

    55/79

    Paso de mensajes

    Permite resolver: Exclusin mutua Sincronizar entre un

    proceso que recibe un

    mensaje y otro que loenva Comunicacin de datos

    entre espacios dememoria diferentes(mismo computador,

    diferentescomputadores) Primitivas bsicas:

    send(destino, mensaje):enva un mensaje alproceso destino

    receive(origen, mensaje):recibe un mensaje del

    Mltiples soluciones Paso de mensajes en POSIX

    (colas de mensajes): Misma mquina

    (uniprocesador,multiprocesador omulticomputador)

    Mecanismo denombrado: connombre local

    Identificacin:identificador especial Buffering: S Unidireccional Sincronizacin:

    bloqueante y no

    bloqueante

  • 7/23/2019 Cs Posix Ssoo2

    56/79

    Colas de mensajes POSIX

    mqd_t mq_open(char *name, int flag, mode_tmode, mq_attr *attr);

    Crea una cola de mensajes con nombre y

    atributos attr: Nmero mximo de mensajes. Tamao mximo del mensaje. Bloqueante, No bloqueante.

    int mq_close (mqd_t mqdes); Cierra una cola de mensajes.

    int mq_unlink(char *name); Borra una cola de mensajes.

  • 7/23/2019 Cs Posix Ssoo2

    57/79

    Colas de mensajes POSIX (II)

    int mq_send(mqd_t mqdes, char *msg, size_t len, int prio);

    Enva el mensaje msg de longitud len a la cola demensajes mqdes con prioridadprio;

    Si la cola est llena el envo puede ser bloqueante o no. int mq_receive(mqd_t mqdes, char *msg, size_t len, int *prio);

    Recibe un mensaje msg de longitud len de la cola demensajes mqdes (el de mayor prioridad). Almacena laprioridad del mensaje en el parmetroprio;

    Recepcin bloqueante o no.

  • 7/23/2019 Cs Posix Ssoo2

    58/79

    Secciones crticas con colasde mensajes

    void main(void){ mqd_t mutex; /* cola de mensajes para sincronizar

    acceso a la seccin crtica */ struct mq_attr attr; /*atributos cola de mensajes*/

    char c; /* carcter para sincronizar */

    attr.mq_maxmsg = 1; /* nmero mximo mensajes */ attr.mq_msgsize = 1; /* tamao mensaje */ mutex = mq_open(``MUTEX'', O_CREAT|O_RDWR, 0777,

    &attr);

    mq_send(mutex, &c, 1, 0); /* entrar en la seccin crtica la primera vez */

  • 7/23/2019 Cs Posix Ssoo2

    59/79

    Secciones crticas con colasde mensajes (II)

    if (fork() == 0) { /* proceso hijo */ for(;;){ mq_receive(mutex, &c, 1, NULL);/*entrada sec. crtica */ /* seccin crtica */ mq_send(mutex, &c, 1, 0); /* salida sec. critica */ } }else { /* proceso padre */ for(;;){ mq_receive(mutex, &c, 1, NULL);/*entrada sec. crtica */ /* seccin crtica */ mq_send(mutex, &c, 1, 0); /* salida sec. critica */ } } }

  • 7/23/2019 Cs Posix Ssoo2

    60/79

    Productor-consumidor concolas de mensajes

    #define MAX_BUFFER 1024 /* tamao del buffer */ #define DATOS_A_PRODUCIR 100000 /*datos a producir*/

    mqd_t almacen; /* cola de mensaje para almacenamiento

    de datos */ void main(void) { struct mq_attr attr;

    attr.mq_maxmsg = MAX_BUFFER; attr.mq_msgsize = sizeof(int);

    almacen = mq_open("ALMACEN", O_CREAT|O_RDWR, 0777,&attr);

  • 7/23/2019 Cs Posix Ssoo2

    61/79

    Productor-consumidor concolas de mensajes (II) if (almacen == -1) { perror("mq_open"); exit(1);

    }

    if (fork() == 0) /* proceso hijo */ Productor(); else /* proceso padre */ Consumidor();

    exit(0);

    }

  • 7/23/2019 Cs Posix Ssoo2

    62/79

    Productor-consumidor concolas de mensajes (III)

    void Productor(void) { int dato; int i;

    for(i=0; i < DATOS_A_PRODUCIR;

    i++ ){ /* producir dato */ dato = i; printf("Produce

    %d \n", dato); mq_send(almacen,

    &dato, sizeof(int),0);

    } return;

    }

    void Consumidor(void){ int dato; int i;

    for(i=0; i cola,O_RDWR);

    pthread_mutex_lock(mutex); n_lectores ++; peticion.tipo = OK;

    mq_send(cola_local, peticion,sizeof(peticion), 0);

    mq_receive(cola_local, peticion,sizeof(peticion), NULL);

    n_lectores --; if (n_lectores == 0)

    pthread_cond_signal(&no_lectores)

    ; pthread mutex unlock(mutex);

    void do_write(struct peticion_t*pet) {

    mqd_t cola_local; struct peticion_t peticion;

    /* abre la cola del proceso querealiza la peticion */

    cola_local = mq_open(pet->cola,O_RDWR);

    pthread_mutex_lock(mutex); while (n_lectores > 0)

    pthread_cond_wait(&no_lectores,

    &mutex);

    peticion.tipo = OK; mq_send(cola_local, peticion,

    sizeof(peticion), 0); mq_receive(cola_local, peticion,

    sizeof(peticion), NULL); pthread_mutex_unlock(mutex); }

    S id l i h d

  • 7/23/2019 Cs Posix Ssoo2

    67/79

    Servidor multithread concolas de mensajes

    P r o c e s o c l i e n t e

    C o l a d e lc l i e n t e

    P r o c e s o c l i e n t e

    C o l a d e lc l i e n t e

    C o l a d e ls e r v i d o r

    P r o c e s o s e r v i d o r

    p e t i c i n

    p e t i c i n

    r e s p u e s t a

    r e s p u e s t a

    C r e a c i n d e lt h r e a d

    C r e a c i n d e l

    t h r e a d

    T h r e a d q u es i r v e l a p e t i c i n

    T h r e a d q u es i r v e l a p e t i c i n

    S id ltith d

  • 7/23/2019 Cs Posix Ssoo2

    68/79

    Servidor multithread concolas de mensajes (II)

    /* estructura de un mensaje */ struct mensaje { char buffer[1024]; /* datos a enviar */ char cliente[256]; /* cola del cliente */ };

    /* mutex y var. condicionales proteccin de la copia del mensaje */ pthread_mutex_t mutex_mensaje; int mensaje_no_copiado = TRUE; pthread_cond_t cond;

    void main(void) { mqd_t q_servidor; /* cola del servidor */ struct mensaje mess; /* mensaje a recibir */ struct mq_attr q_attr; /* atributos de la cola */ pthread_attr_t t_attr; /* atributos de los threads */ q_attr.mq_maxmsg = 20; q_attr.mq_msgsize = sizeof(struct mensaje);

    S id ltith d

  • 7/23/2019 Cs Posix Ssoo2

    69/79

    Servidor multithread concolas de mensajes (III) q_servidor = mq_open("SERVIDOR", O_CREAT|O_RDONLY, 0700,

    &q_attr); pthread_mutex_init(&mutex_mensaje, NULL); pthread_cond_init(&cond, NULL); pthread_attr_init(&t_attr); pthread_attr_setscope(&t_attr,PTHREAD_SCOPE_SYSTEM); pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED); while (TRUE) { mq_receive(q_servidor, &mess, sizeof(struct mensaje), NULL);

    pthread_create(&thid, &t_attr, tratar_mensaje, &mess);

    /* se espera a que el thread copie el mensaje */ pthread_mutex_lock(&mutex_mensaje); while (mensaje_no_copiado) pthread_cond_wait(&cond, &mutex_mensaje); mensaje_no_copiado = TRUE; pthread_mutex_unlock(&mutex_mensaje); } }

    S id ltith d

  • 7/23/2019 Cs Posix Ssoo2

    70/79

    Servidor multithread concolas de mensajes (IV)

    void tratar_mensaje(struct mensaje *mes){ struct mensaje mensaje_local; struct mqd_t q_cliente; /* cola del cliente */ struct mensaje respuesta; /* mensaje de respuesta al cliente */ /* el thread copia el mensaje */ pthread_mutex_lock(&mutex_mensaje); memcpy((char *) &mensaje_local, (char *)&mes, sizeof(struct mensaje)); /* ya se puede despertar al servidor*/ mensaje_no_copiado = FALSE; pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex_mensaje);

    /* ejecutar la peticin del cliente y preparar respuesta */

    /* responder al cliente a su cola */ q_cliente = mq_open(mensaje_local.cliente, O_WRONLY); mqsend(q_cliente, (char *) &respuesta, sizeof(respuesta), 0); mq_close(q_cliente); pthread_exit(0); }

  • 7/23/2019 Cs Posix Ssoo2

    71/79

    Ejemplo de cdigo cliente struct mensaje {/* estructura mensaje

    */ char buffer[1024]; /* datos envo

    */ char cliente[256]; /* cola cliente

    */

    };

    void main(void) { mqd_t q_servidor; /* cola servidor

    */ mqd_t q_cliente; /* cola cliente

    */ struct mq_attr attr; /* atr. cola

    */ struct mensaje peticion; /* peticion

    al servidor*/

    struct mensaje respuesta; /*respuesta delservidor */

    q_cliente = mq_open("CLIENTE",O_CREAT|O_RDONLY, 0700,

    0); q_servidor =

    mq_open("SERVIDOR",O_WRONLY);

    /* preparar peticion */ mq_send(q_servidor, &peticion,

    sizeof(struct mensaje),0);

    /* esperar respuesta */ mq_receive(q_cliente,

    &respuesta,sizeof(struct mensaje), NULL);

    mq_close(q_servidor); mq_close(q_cliente); mq_unlink("CLIENTE");

    exit(0); }

  • 7/23/2019 Cs Posix Ssoo2

    72/79

    Sockets

    Permiten comunicar: Procesos del mismo computador Procesos conectados a travs de una red

    Tipos de direcciones: Direcciones locales: dominio UNIX Direcciones de red (TCP/IP)

    Direccin de red (direccin IP) Puerto

  • 7/23/2019 Cs Posix Ssoo2

    73/79

    Sockets (II)

    Red deinterconexin

  • 7/23/2019 Cs Posix Ssoo2

    74/79

    Resumen Pipes:

    Mecanismo decomunicacin ysincronizacin

    Mecanismo denombrado: sinnombre

    Identificacin: descriptorde fichero

    Flujo de datos:unidireccional

    Buffering: S Sincronizacin:

    Si pipe vaco read() se bloquea

    Si pipe lleno write() sebloquea

    FIFOS: Mecanismo de

    comunicacin ysincronizacin

    Mecanismo denombrado: connombre local

    Identificacin:descriptor de fichero

    Flujo de datos:unidireccional

    Buffering: S Sincronizacin:

    Si FIFO vaco read() sebloquea

    Si FIFO lleno write() se

  • 7/23/2019 Cs Posix Ssoo2

    75/79

    Resumen (II) Semforos POSIX:

    Mecanismo desincronizacin

    Mecanismo de

    nombrado: sinnombre y connombre local

    Identificacin:variable de tiposemforo

    Mutex y variablescondicionales: Mecanismo de

    sincronizacinadecuado paraprocesos ligeros

    Mecanismo denombrado: sin

    Colas de mensajesPOSIX:

    Mecanismo decomunicacin y

    sincronizacin Mecanismo de

    nombrado: connombre local

    Identificacin:identificadorespecial

    Buffering: S Unidireccional Sincronizacin:

    bloqueante y no

    bloqueante

  • 7/23/2019 Cs Posix Ssoo2

    76/79

    Resumen (III)

    Objetos de memoria compartida: Mecanismo de comunicacin Mecanismo de nombrado: con nombre local

    Identificacin: identificador especial Sockets:

    Mecanismo de comunicacin y sincronizacin Mecanismo de nombrado: con nombre de red

    Identificacin: descriptor de fichero Buffering: S Sincronizacin: bloqueante y no bloqueante

  • 7/23/2019 Cs Posix Ssoo2

    77/79

    Interbloqueos Bloqueo permanente de un

    conjunto de procesos quecompiten por los recursosdel sistema o se comunican

    entre s. Ejemplo: Si S y Q con

    semforos con valor inicial P0 P1 s_espera(S)

    s_espera(Q)

    s_espera(Q)s_espera(S)

    . .

    s_abre(S)s_abre(Q)

    s_abre(Q)s_abre(S)

    Ejemplo: Si C1 y C2 son doscolas de mensajes

    P0 P1

    receive(C1, M)receive(C2, N)

    . .

    send(C2, M) send(C1,N)

    Condiciones del

    interbloqueo: Exclusin mutua Retencin y espera No apropiacin Espera circular

  • 7/23/2019 Cs Posix Ssoo2

    78/79

    Ejemplo

    Ejemplo: Si P y Q son semforos con valorinicial 1

    A B

    s_espera(P) s_espera(Q) s_espera(Q) s_espera(P)

    Interbloqueo

    Q

    P

    BA

    Mtodos para tratar con los

  • 7/23/2019 Cs Posix Ssoo2

    79/79

    Mtodos para tratar con losinterbloqueos

    Ignorarlos UNIX

    Solucionarlos: Mtodos para prevenir los interbloqueos Mtodos para evitar los interbloqueos Mtodos para detectar los interbloqueos


Recommended