Unix Programacion Practica

20
UNIX' PROGRAMACIÓN PRÁCTICA Guía para la Concurrencia, la Comunicación y los Multihilos RPC y el modelo cliente-servidor Señales de tiempo real POSIX Multihilos de control POSIX y sincroniz, pH H I'KKMIIT. HAI.I. A Simón & Schuster Company Kay A. Robbins Steven Robbins

Transcript of Unix Programacion Practica

Page 1: Unix Programacion Practica

UNIX' PROGRAMACIÓN PRÁCTICA Guía para la Concurrencia, la Comunicación y los Multihilos

RPC y el modelo cliente-servidor

Señales de tiempo real POSIX

Multihilos de control POSIX y sincroniz,

p H H

I ' K K M I I T . HAI.I .

A Simón & Schuster Company

Kay A. Robbins Steven Robbins

Page 2: Unix Programacion Practica
Page 3: Unix Programacion Practica

POKTIFIGI* WHVt* MD QAIOURA t»tl PM(I B I B L I O T E C A COMPRA

UNIX PROGRAMACION PRACTICA

Page 4: Unix Programacion Practica
Page 5: Unix Programacion Practica

UNIX PROGRAMACION PRÁCTICA

— . . . — -

-PRIMERA EDICION

Kay A. Robbins y Steven Robbins The Univesity of Texas at San Antonio

TRADUCCIÓN:

Roberto Escalona García M. en C, UNAM, México

REVISIÓN TÉCNICA:

Gabriel Guerrero Doctor en Informática

Universidad de París VI

P R E N T I C E - H A L L HISPANOAMERICANA, S.A.

MÉXICO • NUEVA Y O R K • BOGOTÁ • LONDRES • SYDNEY PARÍS • MUNICH • TORONTO • NUEVA DELHI • TOKIO

SINGAPUR • RÍO DE JANEIRO • ZURICH

Page 6: Unix Programacion Practica

EDICIÓN E N ESPAÑOL:

D I R E C T O R G E N E R A L : G E R E N T E DIVISION C O L L E G E : G E R E N T E E D I T O R I A L C O L L E G E : G E R E N T E D E E D I C I O N E S : G E R E N T E D E PRODUCCIÓN : G E R E N T E D E TRADUCCIÓN : D I R E C T O R D E E D I C I O N E S : SUPERVISORA D E TRADUCCIÓN : SUPERVISORA D E PRODUCCIÓN:

EDICIÓN EN INGLÉS:

Editorial/production supervisión: Jane Bonnell Cover design director: Jerry Votta Cover design: Lundgren Graphics, Ltd. Manufacturing manager: Alexis R. Heydt Acquisitions editor: Gregory G. Doench Editorial assistant: Meg Cowen

MOISÉS PÉREZ Z A V A L A JOSÉ T O M A S PÉREZ B O N I L L A LUIS G E R A R D O CEDEÑO P L A S C E N C I A JUAN A N T O N I O RODRÍGUEZ M O R E N O JULIÁN E S C A M I L L A L I Q U I D A N O JORGE B O N I L L A T A L A V E R A A L B E R T O SIERRA O C H O A ROCÍO C A B A N A S CHÁVEZ O L G A A D R I A N A SÁNCHEZ N A V A R R E T E

ROBBINS: UNIX PROGRAMACIÓN PRACTICA, la. ed.

Traducido del inglés de la obra: P R A C T I C A L UNIX P R O G R A M M I N G A Guide to Currency, Communication, and Multithreading

All rights reserved. Authorized translation from English language edition published by Prcntice-Hall, Inc. A Simón & Schuster Company.

Todos los derechos reservados. Traducción autorizada de la edición en inglés publicada por Prentice-Hall, Inc. A Simón & Schuster Company.

All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage and retrieval system, without permission in writing from the publisher.

Prohibida la reproducción total o parcial de esta obra, por cualquier medio o método sin autorización por escrito del editor.

Derechos reservados © 1997 respecto a la primera edición en español publicada por: PRENTICE-HALL HISPANOAMERICANA, S.A. Enrique Jacob 20, Col. E l Conde • 53500 Naucalpan de Juárez, Edo. de México !f

UtOGKUlCAINGRMtX. SA I* CU.

ISBN 968-880-959-4 ammuo.w

Miembro de la Cámara Nacional de la Industria Editorial, Reg. Núm. 1524.

Original English Language Edition Published by Prentice-Hall, Inc. A Simón & Schuster Company Copyright © MCMXCVI All rights reserved

ISBN 0-13-443706-3

IMPRESO E N MÉXICO/ PRINTED IN MEXICO

MXE0.PÍ . CJ-.0M13

Page 7: Unix Programacion Practica

A nuestros estudiantes

Page 8: Unix Programacion Practica

Contenido

I Fundamentos

1 ¿Qué es la concurrencia? 1.1 Multiprogramación y multitarea 1.2 Concurrencia a nivel de aplicaciones 1.3 Estándares UNIX 1.4 Programación en UNIX 1.5 Cómo hacer que las funciones sean seguras 1.6 Ejercicio: arreglos de argumento 1.7 Lecturas adicionales

2 Programas y procesos 2.1 Estructura de un programa ejecutable 2.2 Objetos estáticos 2.3 El proceso ID 2.4 Estado de un proceso 2.5 Creación de procesos y el f ork de UNIX 2.6 Llamada wait al sistema 2.7 Llamada exec al sistema 2.8 Procesos en plano secundario y demonios 2.9 Ambiente de los procesos 2.10 Terminación de procesos en UNIX 2.11 Secciones críticas 2.12 Ejercicio: cadenas de procesos 2.13 Ejercicio: abanicos de procesos 2.14 Ejercicio: b i f f sencillo 2.15 Ejercicio: News b i f f 2.16 Lecturas adicionales

3 Archivos 3.1 Directorios y rutas de acceso 3.2 Representación de archivos en UNIX 3.3 Representación de archivos con identificadores 3.4 Filtros y redireccionamiento 3.5 Entubamiento (Pipes) 3.6 Lectura y escritura de archivos 3.7 E/S sin bloqueo

vi

Page 9: Unix Programacion Practica

Contenido v i i

3.8 La llamada seloct . 117 3.9 FIFO 119 3.10 Archivos especiales—el dispositivo Audio 122 3.11 Ejercicio: recorrido de directorios 128 3.12 Ejercicio: sistema de archivo proc 130 3.13 Ejercicio: Audio 133 3.14 Ejercicio: control de la terminal 136 3.15 Lecturas adicionales 137

4 Proyecto: Anillo de procesos 139 4.1 Formación del anillo 140 4.2 Comunicación simple 149 4.3 Exclusión mutua con fichas (tokens) 150 4.4 Exclusión mutua por votación 152 4.5 Elección del líder en un anillo anónimo 153 4.6 Anillo de fichas (toke ring) para comunicación 155 4.7 Procesador con estructura de entubamiento 157 4.8 Algoritmos de anillo paralelos 159 4.9 Anillo flexible 164 4.10 Lecturas adicionales 165

I I Eventos asincronos 167

5 Señales 169 5.1 Envío de señales 170 5.2 Máscara de señal y conjunto de señales 175 5.3 Atrapar e ignorar señales: sigaction 150 5.4 Espera de señales: pause y sigsuspend 182 5.5 Ejemplo: b i f f 185 5.6 Llamadas al sistema y señales 188 5.7 siglongjmp y sigset jmp 191 5.8 Señales de tiempo real 193 5.9 E/S asincrona 197 5.10 Ejercicio: vaciado de estadísticas 201 5.11 Ejercicio: proc Filesystem I I 202 5.12 Ejercicio: Operación en línea de un dispositivo lento 202 5.13 Lecturas adicionales 204

6 Proyecto: Temporizadores 205 6.1 Tiempo en UNIX 206 6.2 Temporizadores de intervalo 210 6.3 Panorama del proyecto 217 6.4 Temporizadores sencillos 219

Page 10: Unix Programacion Practica

viii Contenido

6.5 Configuración de uno de cinco temporizadores 223 6.6 Temporizadores múltiples 233 6.7 Implantación robusta de varios temporizadores 240 6.8 mycron, pequeño servicio tipo Cron pequeño 241 6.9 Implantación de temporizadores POSIX 242 6.10 Lecturas adicionales 250

7 Proyecto: Desarrollo de intérpretes de comando 253 7.1 Un intérprete de comandos sencillo 255 7.2 Redirección 259 7.3 Entubamientos 262 7.4 Señales 266 7.5 Grupos de proceso, sesiones y terminales controladoras 270 7.6 Control de procesos de fondo en ush 274 7.7 Control de trabajo 279 7.8 Control de trabajo para ush 281 7.9 Lecturas adicionales * 285

I I I Concurrencia 287

8 Secciones críticas y semáforos 289 8.1 Operaciones atómicas 291 8.2 Semáforos 296 8.3 Semáforos en POSIX 304 8.4 Semáforos en System V (Spec 1170) 310 8.5 Semáforos y señales 323 8.6 Ejercicio: Semáforos no nombrados POSIX 324 8.7 Ejercicio: Semáforos nombrados POSIX 325 8.8 Ejercicio: Manejador de licencias 326 8.9 Ejercicio: Memoria compartida en System V 328 8.10 Ejercicio: Colas de mensajes del System V 332 8.11 Lecturas adicionales 332

9 Hilos POSIX 333 9.1 Un problema motivador: Vigilancia de descriptores de archivo 335 9.2 Hilos POSIX 347 9.3 Gestión de hilos básica 348 9.4 Usuario de hilos versus hilos de núcleos (¡cernel) 356 9.5 Atributos de los hilos 359 9.6 Ejercicio: Copiado de archivos en paralelo 362 9.7 Lecturas adicionales 364

Page 11: Unix Programacion Practica

Contenido I X

10 Sincronización de hilos 365 10.1 Mutex 367 10.2 Semáforos 373 10.3 Variables de condición 378 10.4 Manejo de señales e hilos 385 10.5 Ejercicio: Servidor de impresión con hilos 395 10.6 Lecturas adicionales 400

11 Proyecto: La máquina virtual no muy paralela 401 11.1 La máquina virtual no muy paralela 403 11.2 Panorama general del proyecto NTPVM 405 11.3 E/S y prueba del despachador 410 11.4 Una sola tarea sin entradas 418 11.5 Tareas secuenciales 420 11.6 Tareas concurrentes 425 11.7 Difusión y barreras 426 11.8 Terminación y señales 427 11.9 Lecturas adicionales 427

I V Comunicación 429

12 Comunicación cliente-servidor 431 12.1 Estrategias cliente-servidor 432 12.2 La interfaz universal de comunicaciones de Internet (UICI) 437 12.3 Comunicación en red 445 12.4 Implementación de UICI con sockets 447 12.5 Interfaz de la capa de transporte (TLI) 453 12.6 STREAMS 460 12.7 Implementación de UICI con STREAMS 465 12.8 UICI segura con respecto de los hilos 469 12.9 Ejercicio: Transmisión de audio 473 12.10 Ejercicio: Servidor de ping 474 12.11 Lecturas adicionales 476

13 Proyecto: Radio por Internet 477 13.1 Panorama general del multiplexor 478 13.2 Comunicación unidireccional 479 13.3 Comunicación bidireccional 481 13.4 El buffer de transmisión 483 13.5 Multiplexión del buffer de transmisión 486 13.6 Receptores de red 487 13.7 Sintonización y desintonización 488 13.8 Difusor de red , 489 13.9 Manejo de señales 489 13.10 Lecturas adicionales 490

Page 12: Unix Programacion Practica

x Contenido

14 Llamadas a procedimientos remotos 491 14.1 Funcionamiento básico 492 14.2 Conversión de una llamada local sencilla en una RPC 497 14.3 Un servicio remoto de números pseudoaleatorios mejorado 508 14.4 Estado del servidor y solicitudes equipotentes 515 14.5 Servicio de archivos equipotente remoto 519 14.6 Vinculación y asignación de nombres a servicios 523 14.7 Fracasos 525 14.8 NFS —Sistema de archivos de red 526 14.9 Hilos y llamadas a procedimientos remotos 531 14.10 Ejercicio: Servidor de archivos sin estados 536 14.11 Lecturas adicionales 538

15 Proyecto: Espacio de tupias 539 15.1 Linda 541 15.2 Richard, un Linda simplificado 544 15.3 Un espacio de tupias Richard sencillo 547 15.4 Pizarrones: Una aplicación de espacio de tupias 555 15.5 Tupias activas en Richard 564 15.6 Espacios de tupias como tupias en Richard 569 15.7 Un servidor multihilo para Richard 573 15.8 Lecturas adicionales 576

Apéndice A Fundamentos de UNIX 577 A . l Cómo obtener ayuda 577 A.2 Compilación 585 A.3 Archivos Makefile 587 A.4 Archivos de encabezado 590 A.5 Enlace y bibliotecas 591 A.6 Ayudas para depuración 593 A.7 Ambiente del usuario 596 A. 8 Lecturas adicionales 598

Apéndice B Implementación de UICI 599 B. l Prototipos de UICI 599 B.2 Implementación con sockets 600 B.3 Implementación TLI 609 B.4 Implementación con flujos 614

B.5 Implementación de UICI segura respecto de los hilos 621

Bibliografía 633

índice 641

Page 13: Unix Programacion Practica

Prefacio

Los sistemas de cómputo están evolucionando con rapidez de las computadoras grandes, a las que se tiene acceso mediante terminales, hacia redes de estaciones de trabajo con varios procesadores. Ideas tales como la concurrencia, la comunicación y el uso de multihilos de control (multithreading) han trascendido la comunidad de investigación y se han extendido hacia el mundo comercial. El programador de aplicaciones debe comprender estos conceptos, y el presente libro está diseñado para hacerlos accesibles en todos sus detalles.

El libro utiliza un enfoque "manos a la obra" en un sentido no tradicional. En el enfoque tradicional, los programadores implementan o modifican un sistema operativo existente para añadirle funcionalidad. Este enfoque brinda una comprensión profunda del diseño básico de sistemas operativos, pero es difícil que los programadores profesionales lo sigan de manera independiente. Cuando es utilizado en una universidad promedio, los profesores invierten un tiempo considerable de clase en cubrir detalles de la implantación, lo que deja poco tiempo para abarcar una gran variedad de temas. Por otra parte, el enfoque tradicional usualmente no proporciona experiencia de programación práctica con construcciones avanzadas de sincro­nización y comunicación. Una alternativa es la presentación teórica. Si bien este tipo de cursos abarca mucho más material, no proporciona al lector una comprensión profunda de los con­ceptos en la práctica.

Programación práctica en UNIX : Una Guía de la concurrencia, la comunicación y el uso de multihilos de control llena el hueco entre los enfoques práctico y teórico al estudio de sistemas operativos al tratar la programación bajo UNIX estándar. El programador profesional puede emplear el libro de manera independiente o como complemento de un libro de referen­cia, tal como el Advanced Programming in the UNIX Environment [86] de Stevens, con lo que obtendrá un mejor conocimiento de los sistemas operativos y de la programación de sistemas. Los estudiantes pueden usar del libro como complemento de un texto tradicional, como el Operating Systems Concepts [80] de Silbershatz y Galvin o el Sistemas Operativos Modernos [92] de Tanenbaum, para aprender sistemas operativos con un enfoque práctico.

Los ejercicios y proyectos hacen que este libro sea único. De hecho, el libro se inició como un proyecto de cuaderno de ejercicios. Después del desarrollo preliminar, resultó evidente que el material necesario para realizar los proyectos se encontraba disperso en muchos lugares, a menudo en libros de referencia que proporcionaban muchos detalles pero un panorama con­ceptual reducido. Desde entonces, el libro ha evolucionado como una referencia autocontenida que descansa sobre los últimos estándares UNIX.

El libro está organizado en cuatro partes, las cuales contienen capítulos de tema y capítu­los de proyecto. Un capítulo de tema cubre material específico y contiene muchos ejemplos y ejercicios breves de la forma "intente esto" o "qué pasa si." Los capítulos de tema terminan con una o más secciones de ejercicios. El libro proporciona ejercicios de programación para muchos conceptos fundamentales en administración de procesos, concurrencia y comunica­ción. Estos ejercicios satisfacen la misma necesidad que los experimentos de laboratorio en un curso tradicional de ciencias. Para comprender los conceptos es necesario utilizarlos amplia-

xi

Page 14: Unix Programacion Practica

xii Prefacio

mente. Los ejercicios están especificados por un desarrollo por pasos y muchos pueden im­plantarse en menos de 100 líneas de código.

Los capítulos de proyecto integran material de varios capítulos de tema mediante el desarrollo de una aplicación extensa. Los proyectos trabajan en dos niveles. Además de ilustrar las ideas de programación, los proyectos conducen a la comprensión de un tema avanzado relacionado con una aplicación. El diseño de éstos se hace por etapas, y muchas ejecuciones completas tienen varios cientos de líneas. Dado que no es necesario escribir una cantidad grande de código, el programador puede concentrarse en la comprensión de los conceptos más que en la depura­ción de código. Para simplificar la programación, los autores tienen bibliotecas disponibles para comunicación por redes.

La siguiente tabla presenta un resumen de la organización del libro, 15 capítulos agrupa­dos en cuatro partes. Los nueve capítulos de tema no dependen de los seis capítulos de proyec­to, y el lector puede omitir éstos al hacer una primera lectura del libro.

Parte Tema del capítulo # Proyecto del capítulo #

I Fundamentos

Concurrencia 1 Proceso 2 Archivos 3

El anillo de fichas 4

II Eventos

asincronos

Señales 5 Temporizadores 6 Capas cracking 7

III Concurrencia

Semáforos 8 Hilos POSIX 9 Sincronía de hilos 10

Máquina virtual 11

IV Comunicación

Cliente-servidor 12

RPC 14 Radio por Internet 13

Espacio de tupias 15

Existen muchas formas de leer el libro. Los tres capítulos de tema de la parte I son un requisito previo para el resto del libro. Los lectores pueden estudiar las partes I I a la IV en cualquier orden después de leer los capítulos de tema de la parte I . La excepción es el estudio, al final de los últimos capítulos, sobre las interacciones (esto es, la forma en que los hilos de control interactúan con las señales).

Los autores suponen que los lectores de este libro son buenos programadores en C, aunque no necesariamente programadores en C de UNIX. El lector debe estar familiarizado con la

Page 15: Unix Programacion Practica

Prefacio xiii

programación en C y las estructuras de datos básicas. El apéndice A cubre los aspectos esen­ciales del desarrollo de programas para lectores que no tienen experiencia en UNIX. Es proba­ble que los programadores de UNIX conozcan ya buena parte del material presentado en los capítulos 2 y 3, pero la cobertura es bastante detallada y muchos de los proyectos finales dependen en buena medida de este material.

El lector no debe dar por sentado que la lectura de un capítulo es suficiente para compren­der los conceptos, a menos que desarrolle con éxito algunos programas que hagan uso de éstos. Para un programador profesional, los ejercicios que se encuentran al final de los capítulos de tema proporcionan una introducción práctica mínima al material. En general, el profesor que haga uso de este libro para un curso de sistemas operativos puede seleccionar varios ejercicios más uno de los proyectos grandes para ejecutarlos durante el semestre. Cada proyecto tiene muchas variaciones, así que puede emplearse en varios semestres.

El libro incluye una sinopsis de muchas funciones estándares. Los estándares importantes que especifican la función aparecen en la esquina inferior derecha del cuadro de sinopsis. En general, ISO C es un subconjunto de POSIX. 1 y Spec 1170. En algunos casos, la lista de archivos de encabezado requerida difiere entre estándares, donde algunos archivos de encabe­zado son opcionales para algunos estándares. En estos casos, el cuadro de sinopsis contiene una lista con todos los archivos de encabezado importantes.

Un libro como este nunca termina, pero teníamos que detenernos. Agradeceremos los comentarios y sugerencias de los lectores, los cuales pueden enviarlos por (correo electrónico) a pup@vip. es . u t sa . edu. Puede obtenerse información sobre el libro en WWW h t t p : / / v i p . es . u t s a . edu/pup. Todo el código incluido en el libro puede obtenerse de WWW o por ftp anónimo a v i p . es . u t sa . edu, en el directorio pub/pup.

Agradecimientos Nuestro reconocimiento más sincero es para Neal Wagner —amigo, colega y policía de la voz pasiva. Neal es el responsable, más que cualquier otro, de la escritura de este libro. Después de todo, argumentaba, si ya tienen los proyectos, ¿cuánto trabajo más representa escribir un l i ­bro? Después de esto, él nos proporcionó mucha ayuda —lectura y crítica una y otra vez de las versiones previas del material, lo que mejoró considerablemente el libro.

Nuestro segundo reconocimiento es para la audiencia de los más de doce cursos sobre sistemas operativos que impartimos entre 1988 y 1995, que es el periodo durante el cual se desarrolló este material. Agradecemos a los estudiantes de estos cursos por sufrir las versiones previas del libro durante el desarrollo de éste y por poner a prueba los proyectos a medida que iban surgiendo. Los errores en sus programas, sus comentarios, las quejas y sugerencias mejo­raron mucho el libro y nos proporcionaron una idea más acabada de la forma en que se relacio­nan los temas.

También damos las gracias a muchas otras personas que leyeron el libro e hicieron suge­rencias o correcciones para mejorarlo, o que nos ayudaron de otras maneras. Dennis Cadena leyó la versión preliminar e hizo muchas sugerencias. Otras personas que nos hicieron comenta­rios o ayudaron en otras formas son Jeff Adamek, Laura Connor, Sandy Dykes, Richard Hatch, Philip Helsel, Robert Hiromoto, Clint Jeffery, George Leach, C. Ed Nicol, Richard Rybacki, Robert Shenk, Devang Shah, Dennis Wenzel y Andrea Whitlock.

Page 16: Unix Programacion Practica

xiv Prefacio

También damos las gracias a Greg Doench, nuestro editor en Prentice Hall, y a Meg Cowen, su asistente, por orientarnos en todo el proceso. Ellos nos ayudaron a mejorar el libro haciendo sugerencias y brindándonos su amable apoyo sin presionarnos. También queremos dar las gracias a Jane Bonnell, nuestro editor de producción, por toda la ayuda que nos brindó para publicar el libro. Fue un placer trabajar con estos profesionales. Muchos revisores anónimos hicieron sugerencias excelentes que nos ayudaron mucho en la revisión final del libro. La formación del libro se hizo utilizando IATgX2f:, y deseamos expresar nuestro aprecio a sus productores por proporcionar este software sin costo alguno.

Gracias especialmente a nuestras esposas e hijos por la paciencia que tuvieron mientras preparábamos este libro. Finalmente, queremos hacer un reconocimiento a la National Science Foundation por proporcionarnos apoyo a través del financiamiento NSF-ILI USE-0950497 para construir un laboratorio de modo que tuviéramos la oportunidad de desarrollar el currículo original en el que se basa este libro.

Page 17: Unix Programacion Practica

Parte I

Fundamentos

Page 18: Unix Programacion Practica
Page 19: Unix Programacion Practica

Capítulo 1

¿Qué es la concurrencia?

La concurrencia se refiere al hecho de compartir recursos en el mismo marco de tiempo. Esto por lo común significa que varios procesos comparten la misma CPU (esto es, son ejecutados concurrentemente) o la memoria o un dispositivo de E/S. El manejo inco­rrecto de la concurrencia puede dar como resultado programas que fallan sin razón aparente, incluso con la misma entrada para la que parecía que trabajaban perfecta­mente. Los sistemas operativos administran los recursos compartidos, y en el pasado los programadores podían permitir que el sistema manejara todos los aspectos de la concurrencia. En el caso de los programas complejos desarrollados en la actualidad, los cuales necesitan ejecutarse con eficiencia en las computadoras modernas, ya no es así. Las máquinas de escritorio con varios procesadores y los sistemas distribuidos son ejemplos de arquitecturas en las que el control de la concurrencia adquiere un significado nuevo e importante para los diseñadores de sistemas. Este capítulo pre­senta el tema de la concurrencia y proporciona lineamientos para la programación en sistemas UNIX en un ambiente concurrente.

La potencia de cómputo ha aumentado de manera geométrica durante casi 50 años [60] en muchas áreas, incluyendo la velocidad de cómputo, la capacidad de memoria y de almacenamiento masivo, la complejidad de los circuitos, la confiabilidad del hardware y el ancho de banda E/S. Este crecimiento continuó en la década pasada, junto con entubamientos (pipelines), instrucciones de ejecución traslapada en una sola CPU, la colocación de varias CPU en un escritorio, y la explosión en la conectividad de redes.

El aumento tan marcado en la comunicación y la potencia de cómputo ha iniciado cambios fundamentales en el software comercial. Las bases de datos grandes así como otras aplicacio­nes, que antes se ejecutaban en una máquina central conectada con varias terminales, ahora están distribuidas sobre máquinas más pequeñas y de menor precio. Las terminales han abierto camino a las estaciones de trabajo de escritorio, con interfaces de usuario de gráficas y capaci-

3

Page 20: Unix Programacion Practica

4 Capítulo 1. ¿Qué es la concurrencia?

dades para multimedia. En el otro extremo del espectro, las aplicaciones de cómputo personal han evolucionado hacia el uso de comunicaciones por redes. Una hoja de cálculo ya no es un programa aislado que sólo apoya a un usuario debido a que una actualización de la hoja de cálculo puede provocar la actualización automática de otras aplicaciones ligadas con ella, por ejemplo, gráficas de datos o la realización de las proyecciones de ventas. Aplicaciones tales como la edición cooperativa, las conferencias, y los pizarrones blancos, facilitan el trabajo y la interacción entre grupos. Las tendencias de cómputo van hacia la compleja compartición de datos, la interacción en tiempo real de las aplicaciones, las interfaces de usuario inteligentes, y los flujos de datos complejos que incluyen audio y video, además de texto.

Todos estos desarrollos dependen de la comunicación y la concurrencia. La comunicación es el transporte de información de una entidad a otra. La concurrencia es la compartición de recursos en el mismo marco de tiempo. Cuando dos programas se ejecutan en el mismo siste­ma de modo que la ejecución de éstos está entrelazada en el tiempo, entonces ellos comparten un recurso del procesador. Los programas también pueden compartir datos, código y disposi­tivos. Las entidades concurrentes pueden ser hilos de control (threads) de ejecución dentro de programas o dentro de otros objetos abstractos. La concurrencia también puede presentarse en un sistema con una sola CPU. De hecho, uno de los trabajos más importantes de un sistema operativo moderno es administrar las operaciones concurrentes de un sistema de cómputo.

Tratar con la concurrencia no es fácil: los programas concurrentes no siempre se compor­tan como se espera, y los errores comunes en estos programas no siempre aparecen de manera regular. (El problema puede aparecer sólo una vez en un conjunto de un millón de ejecucio­nes.) No hay ningún sustituto a la experiencia práctica con estos conceptos. Este capítulo describe ejemplos de concurrencia, comenzando con la más simple de las situaciones en las que puede ocurrir. El resto del libro amplía estas ideas y proporciona ejemplos específicos.

1.1 Muí ti programación y multi tarea

Los sistemas operativos administran los recursos del sistema —procesadores, memoria y dis­positivos de E/S, incluyendo teclados, monitores, impresoras, ratones, disquetes, cintas, uni­dades de CD-ROM, e interfaces de red. La manera tan complicada en la que al parecer trabajan los sistemas operativos es una consecuencia de las características de los dispositivos periféricos, en particular de la velocidad relativa de éstos con respecto de la CPU o el procesador. La tabla 1.1 proporciona velocidades típicas, en nanosegundos, para el procesador, la memoria y los dispositivos periféricos. La tercera columna indica las mismas velocidades pero escaladas por un factor de 100 millones, lo que brinda tiempos en términos de los seres humanos. El tiempo escalado de una operación por segundo es, a grandes rasgos, la rapidez de las viejas calculado­ras mecánicas de hace cincuenta años. Las velocidades citadas se encuentran en constante cambio, pero la tendencia es que las que corresponden al procesador aumenten de manera exponencial, provocando con ello un hueco cada vez mayor en el desempeño entre los procesadores y los periféricos.

Las unidades de disco han mejorado en lo que respecta a la velocidad de acceso, pero la natu­raleza mecánica de éstas limita su desempeño y los tiempos de acceso no mejoran exponencial mente.