Contenidos 1. 1 Programas 1. 1.1 El sistema operativo 1. 1.1.1 Ejecucin del programa 2. 1.1.2 Interrupciones 3. 1.1.3 Administracin de la memoria 4. 1.1.4 Memoria virtual 5. 1.1.5 Multirea 6. 1.1.6 Acceso al sistema de archivos 7. 1.1.7 Manejadores de dispositivos 8. 1.1.8 Redes 9. 1.1.9 Y mucho ms 2. 1.2 Procesos 1. 1.2.1 Caractersticas 2. 1.2.2 Puntos de acceso 3. 1.2.3 Hilos 4. 1.2.4 Comunicacin inter-proceso 3. 1.3 Libreras 1. 1.3.1 Libreras estticas 2. 1.3.2 Libreras dinmicas 3. 1.3.3 Libreras de cdigo 4. 1.3.4 Interfaz de Programacin de Aplicaciones 2. 2 La memoria 1. 2.1 Datos 1. 2.1.1 Sistema numrico binario 2. 2.1.2 Bits, bytes y palabras 3. 2.1.3 Interpretacin de los bytes 2. 2.2 Almacenamiento 1. 2.2.1 Jerarqua de la memoria 2. 2.2.2 Volatibilidad 3. 2.2.3 Diferenciacin 4. 2.2.4 Mutabilidad 5. 2.2.5 Accesibilidad 6. 2.2.6 Direccionamiento 3. 3 Notas Este captulo est dedicado a explorar conceptos bsicos sobre los cules se construye el lenguaje. En el primer apartado, vemos lo que es un programa, cmo se estructura y sus caractersticas principales; qu es la memoria, cmo se usa y todas las directrices lgicas que hay que tener en cuenta. En el segundo apartado, continuamos con el tema de los lenguajes de programacin. Qu son, cmo se clasifican, y hacemos un breve resumen histrico. Tambin vemos qu es lo que distingue a un lenguaje de otro, y los diferentes tipos de lenguajes que hay. Analizamos los diferentes paradigmas que exiten y vemos ventajas y desventajas de stos. En el tercer apartado, nos enfocamos en el proceso de compilacin en general, y de C++ en particular. Vemos el proceso de compilacin, cmo funciona el pre-procesador, los anlisis sintctico-semntico que debe hacer, la identificacin de smbolos y algunos algoritmos que se especifican para el compilador de C++. A su vez, vemos la parte del enlazado de unidades de compilacin y la generacin final del binario. Terminamos el apartado con una descripcin de los errores comunes que podemos encontrar en el proceso de generacin del binario. El siguiente apartado es una introduccin a C++, en cuanto a lenguaje. Se hace un resumen de la historia de C++ y vemos el concepto de estndar e implementacin. Se explica, adems, el concepto de comportamiento definido y comportamiento indefinido, y las diferencias entre cdigo estndar y cdigo de implementacin. La seccin anterior es la introduccin. La seccin siguiente es la de los primeros pasos. Programas A final de cuentas, de lo que se trata todo esto es de crear programas. Digo, eso hacemos los programadores: crear programas. Para ello nos pagan. Luego entonces, viene la pregunta: qu es un programa? Quizs todos tengamos una idea intuitiva, ya que de una u otra forma los hemos usado (de no ser as, no estaras leyendo esto). Quizs nos imaginemos algo como Word o el Visual Studio o el Internet Explorer. Pero, en esencia, qu es un programa? La definicin ms simple y ms general de un programa es que es un conjunto de instrucciones estructuradas (en nuestro contexto, para una computadora). 1 . Esta definicin pudiese no ser tan ilustrativa, pero muestra un concepto bsico que debemos tomar en cuenta: cuando escribimos un programa, le estamos dando instrucciones. Una computadora, por potente que sea, no sabe cmo pensar por s misma. No tiene conceptos y nociones (lgicas y matemticas) que nosotros s tenemos, no puede abstraer (una computadora no puede entender el concepto del cero) y en resumen, no piensa por s misma. Nuestro trabajo al hacer un programa es ese: decirle a la computadora qu hacer. Y adems hay que decrselo paso a paso. Una computadora no tiene el criterio propio para inferir un paso intermedio. Eso corre por nuestra cuenta. El saltarnos un paso normalmente es un error lgico del programador. La computadora no va a inferir nada. A manera de ejercicio mental, consideremos el siguiente ejemplo. Vamos a hacer un programa que sume unos nmeros de forma indefinida. Estas seran las instrucciones: 1. Establecer el contador a cero 2. Establecer el nmero a uno 3. Sumar el nmero al contador 4. Aadir uno al nmero 5. Comparar el nmero con 1000 6. Si el nmero es menor o igual a 1000, regresar a la tercera instruccin 7. Terminar el programa Una vez que se ejecute este programa, la computadora correr de forma indefinida sin intervencin humana. Difcilmente hara un error, y una computadora moderna ejecutara estas instrucciones en millonsimas de segundo. Pero como les deca, la computadora no puede pensar por s misma. Ejecutar las sentencias tal y como se le ha indicado, pero no ir un paso ms all. En efecto, un humano que tuviese que hacer la suma anterior rpidamente se dara cuenta de que el ejercicio se reduce a una simple ecuacin: n(n + 1) 1 + 2 + 3 + ... + n = ------------ 2 y llegara a la respuesta correcta con muy poco esfuerzo. Pero una computadora nunca podra darse cuenta de lo anterior. Evidentemente, la anterior definicin es muy sencilla y abarca toda una gama enorme de posibilidades. En ese tenor, cualesquiera instrucciones ordenadas forman un programa. Esto es interesante, ya si definimos lo que es una computadora en funcin de la definicin sencilla de programa, tenemos que una computadora es un dispositivo que ejecuta programas. Y esto nos lleva a una definicin muy amplia en la cul un programa no necesariamente tiene que ser corrido por una computadora. De hecho, uno de los padres de la computacin, Charles Babbage (1791-1871), origin el concepto de mquinas programables al disear su mquina analtica, la cul pretenda ser una mquina programable a travs de tablas con agujeros para calcular tablas numricas. Los agujeros en las tarjetas hacan que el dispositivo moviera sus engranes de una u otra forma, de tal suerte que se pudiese obtener el resultado deseado. Aunque Babbage nunca pudo ver su sueo consumado, ni duda cabe de que su mquina analtica, a pesar de ser mecnica, motiv al mundo a buscar mquinas programables. Una de las personas motivadas fue la condesa Ada Lovelace (1815-1852), matemtica que comprendi bien las ideas de Babbage, cre un programa para la mquina analtica, el cul calculaba la secuencia de nmeros de Bernoulli. Si Babbage hubiera podido construir su mquina, el programa de Ada hubiese funcionado a la perfeccin. Gracias a ello, la condesa es considerada como la primera programadora del mundo, y el lenguaje de programacin Ada lleva su nombre en su honor. Volvamos al concepto de programas modernos para computadoras electrnicas y olvidmonos del dato curioso de la mquina analtica de Babbage. Un programa puede llegar a tener miles de instrucciones, pero cmo la mquina entiende estas instrucciones? La respuesta a la pregunta anterior es muy compleja y en general tiene ms que ver con el hardware. Para los propsitos de este tutorial, baste decir que una computadora entiende un arreglo complicado de ceros y unos (binario) y en base a eso hace sus operaciones. Escribir un programa moderno en cdigo binario, sin embargo, es exageradamente complicado en nuestros das, y nunca tendremos que hacer algo semejante. En su lugar, hacemos un paso intermedio que consiste en escribir las instrucciones de alguna forma estructurada y con reglas bien definidas (a lo que llamamos lenguaje de programacin) y luego usamos un programa que traduzca las instrucciones en cdigo que la mquina pueda entender (proceso al que llamamos compilar, y al programa que hace esta traduccin lo llamamos compilador, por obvias razones). Veremos estos conceptos un poco ms adelante. Pero a ver, significa eso entonces que yo programador tengo que decirle a la computadora cundo y cmo hacer cualquier cosa? S, eso significa. Si quieres abrir un archivo, tienes que comunicarte con el hardware (disco duro, en este caso) y decirle que vas a leer un sector en el disco. Esto significa que le vas a decir al disco duro cmo se organiza la memoria, cmo leer los segmentos, cmo hacer el guardado de archivos (i.e. la transferencia de bytes), cmo persistirla, y un largusimo etctera. Y lo mismo para cada uno de los diversos perifricos y dispositivos que tenga la computadora: el monitor, el ratn, el teclado, el procesador, los buses, la tarjeta de vdeo, la tarjeta de audio, la cmara web... absolutamente todo. Y ya sobre eso, construimos la lgica de lo que nuestro programa har. Estars de acuerdo conmigo en que tener que programar todo esto cada vez que escribo un programa es algo tedioso, repetitivo y sin duda una prdida de tiempo. Antes de 1970, as era la vida del programador. Durante la dcada de los sesentas, se pens en alguna forma de solventar este problema: un programa que hiciera todo eso, y que se pudiera comunicar con otros programas, es decir una forma de automatizar estos procesos repetitivos. Surgi entonces el concepto de sistema operativo. El sistema operativo Y bueno, digo yo, qu es un sistema operativo? Tambin es un programa, y uno bastante complejo. Es un programa que se encarga de administrar los recursos del sistema (i.e. la computadora) al comunicarle al harware cmo debe de funcionar. Por otro lado, un sistema operativo expone una serie de interfaces a travs de las cules un programa puede hacer uso de sus servicios (como por ejemplo, pedirle que guarde un archivo en disco duro). Desde este punto de vista, el sistema operativo es un anfitrin de aplicaciones. La motivacin principal que hay detrs del concepto de sistema operativo es precsamente que las aplicaciones no tengan que preocuparse por la administracin de los recursos que usualmente se encuentran en una computadora, como la memoria RAM, el disco duro, el teclado, el monitor, etc. As, puedo enfocarme a desarrollar la lgica de mi aplicacin y dejarle al sistema operativo todas estas tareas repetitivas y aburridas. La gama de servicios que un sistema operativo ofrece son diversas y han variado a lo largo del tiempo. Los sistemas operativos modernos proven los siguientes servicios: Ejecucin del programa Interrupciones Administracin de la memoria Memoria virtual Multirea Acceso al sistema de archivos Manejadores de dispositivos Redes Veamos qu tiene que ver cada una de estos servicios con nuestros programas. Ejecucin del programa La finalidad del sistema operativo es proveer de servicios a nuestros programas. Por ende, la ejecucin de un programa es la parte central de su razn de ser. El ejecutar un programa conlleva una serie de actividades antes, durante y despus de la ejecucin del mismo. Cuando pedimos que se inicie un programa, el sistema operativo realizar varias actividades, como abrir manejadores, archivos y una serie de operaciones internas que varan entre sistemas. A nivel general, har tres actividades antes de pasarle el control al programa: iniciar un proceso, asignarle memoria e inicializar los recursos que pudise necesitar (como manejadores de archivos y dependencias). El concepto de proceso lo vemos adelante en otro apartado. Por el momento, digamos que un proceso es el programa mismo que tiene un hilo de ejecucin. En cuanto a la memoria, que tambin explicamos posteriormente, baste decir que tiene que ser inicializada y asignada para que el proceso pueda hacer uso de ella. Finalmente, las dependencias son otros programas que se cargarn en la memoria del proceso para poder ser invocadas por el propio programa. Durante la ejecucin del programa, el sistema operativo se dedicar a recibir las peticiones que le haga el programa, ejecutarlas y devolver un resultado. Si el programa requiere ocupar memoria para guardar algn valor en particular, el sistema operativo se encarga de asignrselo. Si el programa requiere escribir datos a un archivo, el sistema operativo tomar el flujo de bytes, modificar la tabla de direcciones del disco y luego serializar los bytes a la direccin de memoria indicada. Si el programa requiere abrir un puerto serial, el sistema operativo le expondr los mtodos para abrir el bus de conexin y leer o escribir los datos. Y as sucesivamente. En particular, el sistema operativo ver todo lo relacionado con el proceso. Esto lo explicamos un poco ms abajo. Paciencia. Interrupciones Este es un concepto importante en el mundo del hardware. Una interrupcin es una seal asncrona emitida por el hardware que indica que hay algo que necesita atencin, o bien lo que conocemos como "evento", es decir, una seal del programa para indicar que hubo una peticin asncrona y se necesita un cambio en la ejecucin del programa. Las interrupciones ayudan cuando se necesita saber el estado de algo (digamos, del hardware) de tal suerte que es mejor esperar a recibir la seal que andar revisando el estado en alguna iteracin, salvndonos algo de tiempo en el proceso. Quizs el ejemplo clsico de una interrupcin sea algn tipo de error. Supongamos que queremos leer un sector de memoria. Nuestro programa asume que ste est en buen estado. Pero si por algn motivo accedemos a memoria no inicializada, o a un sector corrupto, el sistema operativo nos avisar del error a travs de una interrupcin, de una seal, de tal suerte que nuestro programa lo pueda manejar, ya sea para reparar el error, ignorarlo o terminar el programa. Pero hay muchos otros ejemplos de interrupciones. Windows utiliza un sistema basado en interrupciones, llamados mensajes, a travs de los cules avisa al programa que algn evento ha sido ejecutado (como el hacer clic con el ratn). Los sistemas Unix emplean interrupciones cuando algn dispositivo falla, como por ejemplo el sistema grfico o algn manejador de disposiivos. Y as. De esta forma, nuestro programa no se tiene que preocupar por todo esto, simplemente recibir los avisos por parte del sistema operativo y hacer algo con ellos, o bien ignorarlos. Administracin de la memoria La memoria es un recurso bsico. Es donde se guardan los valores que nuestro programa utilizar para llevar a cabo sus funciones. Pero manejar la memoria requiere muchsima atencin. Tanto, que le dedicamos un apartado posterior. Sin embargo, podemos decir que a nivel general, el sistema operativo se encarga de tres tareas fundamentales: 1. Inicializacin de la memoria 2. Asignacin de la memoria 3. Liberacin de la memoria Por supuesto, sistemas modernos hacen ms cosas, como las paginaciones y crear yuxtaposiciones de bloques de memoria, pero estas tres tareas son fundamentalmente las ms importantes. La primera se encarga de limpiar un bloque de memoria y hacerlo vlido, la segunda se encarga de ingresar la direccin de memoria en una tabla que apunta al sector asignado, y la tercera se encarga de liberar la memoria previamente asignada para que pueda volver a ser utilizada. Memoria virtual Un problema recurrente que se tena en los sistemas antiguos era que cuando se acababa la memoria, todos los programas dejaban de funcionar. Un problema de esta naturaleza era catastrfico, ya que el programa poda fallar en cualquier lado, dejando el estado del mismo totalmente indefinido. As, se cre el concepto de memoria virtual. Los sistemas operativos modernos asignan grandes cantidades de memoria. Windows XP le asigna 4GB de memoria a cada programa que inicia (Windows Vista, 64GB). Evidentemente hay pocas computadoras que puedan tener 4GB de memoria, y an si las tuviera, solo un programa podra hacer uso de 4GB a la vez. Lo que hacen los sistemas operativos es asignar memoria "virtual", que no existe. Como la memoria se inicializa bajo demanda solo se har uso de los 4GB hasta que un programa lo solicite. En ese momento, el sistema lanzar un error, pero al menos ya no se tiene esa limitante. La memoria virtual tambin tiene otra funcin. Como decamos antes, si se acaba la memoria fsica, todos los programas truenan, al no poder almacenar ms informacin. Para evitar una catstrofe de proporciones bblicas, los sitemas operativos modernos aprovechan la memoria virtual y hacen un mapeo entre sta y el disco duro. Es decir, emplean el disco duro como si fuese memoria RAM. Por supuesto, es ms lento, pero al menos no se mueren todos nuestros programas (a menos que se acabe la memoria virtual). Esta tambin es labor del sistema operativo. Multirea Un sistema operativo realiza infinidad de tareas, algunas de las cules ya se han mencionado. Estas tareas, empero, no se pueden llevar a cabo de forma secuencial (es decir, una tarea empieza cuando otra acaba, de forma sucesiva). De ser as, imagnate la cantidad de tiempo perdido al tener que esperar a que se asigne memoria, se abran los manejadores, se comunique con el hardware, para realizar una simple accin. Por no mencionar que en ese caso no se podra correr ms de un programa a la vez. Por eso mismo, otra de las tareas principales de los sistemas operativos modernos consiste en distriuir el tiempo de procesamiento que se le asigna a cada programa. A este proceso se le conoce como multirea. Evidentemente esto es una ilusin (la nica forma en la que dos aplicaciones se pueden procesar en paralelo es teniendo dos procesadores), lo que en realidad hacen es distribuir equitativamente dicho tiempo entre las aplicaciones: el programa A tiene 5 milisegundos de proceso, luego se interrumpe y le toca al programa B, luego al C, y as sucesivamente. Bueno, es ms complicado de eso, ya que un programa puede tener prioridad sobre otros, pero a nivel general as funciona. El ncleo del sistema tiene una cosa llamada "calendarizador", el cul determina cunto tiempo puede un programa estar ejecutndose antes de ser interrumpido y pasarle el control a algn otro. A este proceso de pasar el control entre el ncleo y la aplicacin se le llama "intercambio contextual" (context switch). Gracias a esto no tenemos que esperar mucho tiempo, adems de que podemos aprovechar los recursos de nuestra computadora al mximo. Ms an, podemos crear manualmente diversos "hilos" de procesamiento para poder realizar dos o ms actividades al mismo tiempo (a lo que se le llama "concurrencia"). Acceso al sistema de archivos En el inicio solo exista la memoria RAM. Cualquier informacin que se guardara en la memoria, se perda cuando la computadora se reiniciaba. Es ms, al prender una computadora, haba que cargar en memoria los programas antes de usarlos. Por supuesto, cualquier resultado se tena que imprimir para que fuese conservado. Vaya monserga. En algn momento de la vida, a alguien se le ocurri la forma de idear un mecanismo en el cul se pudiese persistir la informacin. Ese algo fueron los ahora llamados discos duros. Supongo que todos estamos ya familiarizados con ellos. Un disco duro se divide en secciones. La primera seccin contiene una tabla donde se guarda el directorio, esto es, se le asigna un nombre calificado a un bloque de memoria. La vida se hizo ms sencilla, ya que ahora los datos y programas se tenan que cargar solo una vez, y los datos que generase el programa se pueden persistir. Pero para ello hay que hacer muchas cosas: leer la tabla de direcciones, navegar al bloque sealado, pedir ms espacio en memoria o liberar la que ya no se usa, leer los bytes del bloque o escribir nuevos. El sistema operativo se va a encargar de realizar todas estas tareas por nosotros, de tal suerte que nos tengamos que ocupar de cosas mnimas. Manejadores de dispositivos En el mundo hay varias empresas que se dedican a hacer hardware. Imaginemos que la empresa A hace algn dispositivo, como un ratn. La empresa B es su competencia y tambin hace ratones. stos se conectan por algn puerto, digamos USB. Pero envan y reciben datos de forma distinta, como se les haya ocurrido a los tcnicos de ambas empresas. Luego entonces, un programa de computadora que quisiera hacer uso del ratn, tendra que escribir una versin que se comunique con el ratn de la empresa A, y otra versin para cuando se comunique con el ratn de la empresa B. Menudo lo, sobre todo cuando hay varias decenas de empresas que los fabrican. Y esto sera igual para cada dispositivo (monitor, teclado, CD-ROM, impresoras, etc). Aunque no lo creas, hace unas cuatro dcadas as tena que ser esto. Para los programadores, esto representaba un problema, ya que por lo general no les importaba si usaban el ratn A o el B. Para ellos, su prioridad era que sus clientes pudiesen usar el dispositivo que ms les conviniera y el que mejor se ajustara a sus bolsillos. Afortunadamente, los sistemas operativos vinieron a resolver este problema con el concepto de manejadores de dispositivos (device drivers, o simplemente drivers). Un driver es un programa que se encarga de comunicar con el hardware. El sistema operativo expone una interfaz estndar para poder comunicarse con el driver, y ste se encarga de comunicarse con el dispositivo. Los programas, a travs del sistema operativo, no llaman al hardware, sino que le piden al driver que haga tal o cul tarea. En resumen, un driver es un programa que acta como intermediario, y el sistema operativo dicta cmo cada tipo de dispositivo debe ser controlado. Redes Hoy en da, la mayora de sistemas operativos soportan diversoso protocolos de redes. Una red es un conjunto de hardware y software que permite que computadoras conectadas entre s se comuniquen y puedan compartir archivos, impresoras y otros dispositivos. En esencia, las redes permiten que el sistema operativo haga uso de los recursos de otro equipo. Sobre las redes, es posible construir programas que interaccionen con los recursos de otras mquinas, creando modelos cliente/servidor, en los cules diversos programas se distribuyen creando parte de un sistema informtico. Por ejemplo, programas como SharePoint se pueden instalar en una mquina, conectarse a una base de datos en otra mquina, instalar servicios de bsqueda en otra, y permitir el acceso a travs de algn navegador de nternet. En algunos sistemas operativos, las redes incluso forman parte de modelos de seguridad ms grandes. Protocolos como LDAP permiten que un usuario ingrese a una mquina con una cuenta y contraseas nicas, y la autenticacin se hace a travs de la red, de tal suerte que dicho usuario pueda usar su misma cuenta en otras mquinas. Windows incorpora el Directorio Activo, el cul est basado en LDAP y permite hasta guardar informacin extra como grupos de trabajo y permisos particulares. Todo esto, administrado por el sistema operativo, de tal suerte que los programadores puedan hacer uso de sus servicios sin tener que preocuparse por manejar todo esto. Y mucho ms Los sistemas operativos modernos como Windows, Linux o Mac no solo limitan sus servicios a los antes mencionados. Con el paso del tiempo, han ido creciendo la gama de herramientas que ofrecen. Por ejemplo, Mac desde hace mucho tiempo ofrece servicios relacionados con multimedia, para facilitar el manejo de imagenes, vdeo y audio. Windows se ha intentado poner al correinte en esto. Linux ofrece muchos servicios de servidor, como acceso a internet, servidores de correo y grupos de noticias. Por supuesto, en ninguno faltan herramientas bsicas como calculadoras y editores de texto. Y ni qu decir tiene, todos incorporan herramientas para la Web, como navegadores de nternet, clientes de correo y paquetes de mensajera instantnea. Es difcil decir hasta dnde debe de llegar los servicios de un sistema operativo. Hay gente que piensa que un sistema operativo debe proveer solo lo bsico. Un ejemplo de esto es el sistema operativo Minix, una versin recortada de Unix (Minix toma su nombre de MINimalistic unIX) originalmente pensada para ensear a los estudiantes a hacer sistemas operativos, y que tan solo contiene lo bsico, como memoria, multirea y acceso al sistema de archivos. Otroas personas piensan que entre ms servicios, mejor. Windows es un ejemplo de esto, ya que incorpora herramientas que no son necesarias para el funcionamiento del sistema, como elementos multimedia y navegadores de nternet (lo que le ha valido ser demandado en varias ocasiones). No cabe duda de que el debate sigue abierto. En cualquier caso, cumplen con su cometido. Ahora ya no nos tenemos que preocupar por programar a bajo nivel (a menos de que sea estrictamente necesario). Los sistemas operativos nos facilitan la vida, sin duda alguna. Procesos Hasta el momento, hemos dado una definicin un tanto vaga y general de lo que es un programa. Al ir explorando este concepto, mencionamos un tipo de programa muy particular, que nos ayuda a manejar tareas repetitivas, generales y de bajo nivel: el sistema operativo. Sin embargo, todava no hemos visto el corazn de un programa: el proceso. Un proceso es una instancia de un programa que es ejecutado secuencialmente por un sistema operativo que tiene la capacidad de ejecutar programas concurrentes. Menuda definicin, que encierra conceptos importantes. Vamos por partes. Mencionamos que era "una instancia de un programa". Ya dijimos que un programa es una serie de instrucciones. A qu nos referimos con que es una instancia? Veamos un ejemplo. Cuando vas a una tienda, compras algn artculo y pides un comprobante de pago, quien atiende seguramente te dar una nota describiendo lo que compraste. Supongo que ests familiarizado con eso. Ahora bien, analiza la nota. Seguramente tiene el logotipo de la tienda as como sus datos fiscales. Tiene un encabezado donde se anota los datos del cliente, y un detalle donde se anotan los productos comprados, su precio unitario, los impuestos y el costo total. Al final, tienes un resumen donde se muestra el total a pagar. Imagnate si el locatario tuviese que hacer todo eso cada vez que entrega una nota: estara de locos. Lo que el locatario hizo seguramente, es ir a alguna papelera y solicitar que le hicieran un bloc de notas de pago. Es decir, ya hay un diseo de la nota, pero luego escriben los datos particulares, arrancan la hojita y te la dan. Pues bien, en nuestro caso imagina a un programa como el bloc de notas de pago, y a una instancia con la nota particular que te da el locatario. En otras palabras, el programa define un comportamiento, mientras que la instancia en particular define una ejecucin del programa que tiene estado propio, o dicho en otras palabras, el programa es simplemente una coleccin pasiva de instrucciones, mientras que la instancia es la ejecucin actual de dichas instrucciones. El programa A es siempre igual, pero si corremos dos veces el mismo programa, en algn punto la instancia 1 va a ser diferente de la instancia 2. A esto nos referimos con instancia. Lo siguiente que decimos es que la instancia es ejecutada "de forma secuencial". Esto quiere decir que se ejecuta una instruccin tras otra, sin parar ni saltarse alguna. As pues, la ejecucin de un proceso siempre ser secuencial y se garantiza que no habr saltos e interrupciones. A menos que el programa as lo indique, ya que en los sistemas modernos es posible crear diferentes secuencias de instrucciones que corran en paralelo, a lo que llamamos hilos (y que son tratados un poco ms adelante en este apartado). Por supuesto, para que tenga sentido el especificar que el programa se ejecuta de forma secuencial, necesitamos que nuestro sistema operativo tenga la capacidad de correr diferentes programas de forma concurrente (i.e. al mismo tiempo). Si no, no tendra sentido, puesto que solo habra un programa y por ende una sola instancia. A esto nos referimos con la ltima parte de la definicin, que dice que la instancia es ejecutada "por un sistema operativo que tiene la capacidad de ejcutar programas concurrentes. As las cosas, un proceso es la ejecucin misma del programa: la instancia. Caractersticas A primera vista pareciera que un proceso no difiere mucho de la definicin que dimos de programa, pero en realidad hay diferencias que normalmente son ocultadas por el sistema operativo, pero que es esencial que conozcamos. Por ejemplo, un proceso tiene una serie de caractersticas asociadas. La imagen. Esto es, una copia del cdigo mquina ejecutable asociado con el programa. Cuando iniciamos un programa, el sistema operativo carga en memoria las instrucciones del mismo, para poderlas ir ejecutando una tras otra. A esto es a lo que le llamamos una imagen. De esta forma, no es necesario tener que estar leyendo del disco duro cada vez que se ejecuta una sentencia, haciendo la ejecucin del programa mucho ms rpido. Memoria. Cuando se inicia un proceso, el sistema operativo asocia un bloque de memoria (generalmente memoria virtualizada) al proceso para que ste pueda ir guardando sus valores. Este bloque no solo se utiliza para guardar los valores que el programa pide, sino que tambin se guardan muchos otros valores, como la misma imagen del programa, una pila de llamados para saber qu subrutinas han sido llamadas y en qu orden, y un montculo para guardar los valores que se generen en tiempo de ejecucin. Descriptores de recursos. Son manejadores para todos los recursos de los que puede echar mano nuestro proceso, como descriptores de archivos (i.e. referencias a archivos), fuentes de datos, eventos y descriptores de seguridad. Atributos de seguridad. No todos los procesos pueden acceder a recursos del sistema (como archivos). Depende de qu usuario es el que mand ejecutar el programa y los permisos que tenga asociados. Es decir, el proceso tiene a un dueo asociado (i.e. quien inici el programa), y ste tiene una serie de permisos. stos son los atributos de seguridad. Estado del procesador. Tambin llamado contexto, hace referencia a los registros del procesador, direcciones de memoria fsica (tanto en disco duro como en la memoria RAM), si ha habido algn error, etc. Como puedes ver, s que hay diferencias entre proceso y programa. Todas las caractersticas anteriormente mencionadas no las tiene un programa dado a su naturaleza propia: al no ser una instancia que ejecuta las instrucciones del programa, no necesita todo eso. Puntos de acceso De las caractersticas mencionadas en la seccin anterior, se deduce que el sistema operativo hace toda una gama de labores antes, durante y despus de que el programa termina. Esto es cierto. Al iniciar el proceso, pero antes de que se ejcute la primera lnea del programa, el sistema operativo llevar a cabo acciones como la carga de imagen, la asignacin de la memoria, la apertura de los descriptores y la asignacin de los atributos de seguridad. Solo hasta que termina de hacer todo esto es que el sistema operativo comienza a ejecutar las rdenes del programa. An as, durante la ejecucin del mismo, el sistema operativo realiza varias funciones como estar analizando el estado del procesador (i.e. el contexto). As, de surgir algn error se generara alguna interrupcin del proceso, sin afectar a los dems (al menos en teora: todos recordamos las famosas pantallas azules de la muerte, tan frecuentes en Windows 95, 98 y ME). Y una vez que el programa ejecuta su tlima instruccin, el sistema operativo tiene que liberar todos los recursos que previamente asoci al proceso. Ms an, cualquier recurso que no haya sido liberado (como bloques de memoria o descriptores de archivos) sern limpiados por el proceso. Por ello mismo es que un programa define uno (o varios) puntos de acceso. stos no son otra cosa que la primera instruccin que ejecutar el programa. Normalmente, dependiendo del sistema operativo o del programa mismo, el punto de acceso debe tener una estructura bien definida. Adelantando algo, en C++ el punto de acceso siempre es una funcon llamada main. Adems, algunos sistemas operativos tienen tipos de programas cuyos puntos de acceso varan. Un servicio de Windows no tiene punto de acceso, ya que siempre se estar ejecutando y nunca terminar: el sistema operativo los inicia y los termina. Una librera de enlaces dinmicos (DLL) en Windows define un punto de acceso diferente para que uno pueda realizar operaciones cuando se carga la librera. Pero ya nos estamos metiendo en temas un poco ms complicados. Por ahora, creo que la explicacin sobre los puntos de acceso es suficiente. Hilos Hace algunos prrafos comentaba que un proceso es quien realmente ejecuta las instrucciones de un programa. Esto es cierto, pero no es preciso. Paso a continuacin a ahondar ms en este tema. Decamos que un proceso es una instancia del programa que ejecuta las instrucciones de ste de forma secuencial. Ahora bien, pensemos. Qu pasa si por algn motivo quiero que mi programa ejecute dos tareas al mismo tiempo? Digamos que mi programa est procesando un archivo muy grande. Para que mi usuario no se aburra o piense que el programa se trab, muestro una ventanita con una barra que muestra el porcentaje de datos procesados. En este escenario, necesito ejecutar dos tareas al mismo tiempo: por un lado, el procesamiento de los datos del archivo, y por el otro necesito calcular el porcentaje en un intervalo de tiempo y actualizar la barra de progreso. Cmo puedo hacer para lograr este objetivo? Un proceso se divide en sub-procesos llamados hilos. Un hilo se ejecuta en paralelo con respecto a otros hilos del mismo proceso. Gracias a esto, nuestro escenario anterior se resuelve de forma sencilla: un hilo har el procesamiento de datos mientras que otro hilo ir actualizando la barra. La capacidad de manejar hilos es conocida como programacin multihilo o multirea. Los hilos heredan algunas de las caractersticas del proceso. Cuando se crea un hilo, el proceso le asigna un pedazo de su bloque de memoria para que sea utiliado por ste. Adems, le comparte descriptores y otros recursos. De hecho, cuando dijimos que el proceso es quien ejecuta las instrucciones, te ment vilmente: en realidad, quien las ejecuta son los hilos. En efecto, cuando se crea un proceso, se crea al menos un hilo: el hilo principal que en realidad ejecutar las instrucciones, las cules pueden pedirle al proceso que cree hilos paralelos, tantos como soporte el sistema operativo. Cuando un proceso solo emplea el hilo principal, decimos que el proceso es uni-hilo (single-threading), y multi-hilo (multi-threading) cuando hay varios. Por supuesto, la comunicacin entre hilos es posible. A final de cuentas, la memoria de los hilos es compartida: toda es asignada por el proceso en cuestin. Claro que no es tan sencillo, y puede ocasionar problemas. Por ejemplo, dos hilos pueden intentar acceder a un mismo valor en memoria al mismo tiempo, lo cul puede ocasionar problemas de concurrencia. De forma similar, si un hilo espera a que un valor en memoria cambie de estado, y el segundo lo regresa a como estaba esperando tambin a que cambie, tenemos una situacin en la que los hilos se bloquearn ya que nunca se cumplirn las condiciones que esperan (a esto se le llama "deadlock"). Hay, pus, que tener cuidado cuando programemos hilos. Comunicacin inter-proceso Los procesos pueden comunicarse con otros procesos a travs de lo que se llama (en un alarde de creatividad) comunicacin inter-proceso (IPC, Inter-process communication), tanto para procesos en la misma mquina como en diferentes mquinas. Sin embargo, esto es un tanto complicado debido a que varia entre sistemas operativos (incluso entre versiones del mismo sistema), y sobre todo, porque como un proceso no comparte el mismo bloque de memoria (virutalizada) que el otro. Pero vale la pena mencionarlo, creo. Libreras Hagamos una pausa y revisemos un poco lo que hemos dicho hasta el momento. Dijimos que un programa es una serie de instrucciones estructuradas. Dijimos tambin que hay una especie de programa, el sistema operativo, que se encarga de adminsitrar los recursos del sistema, y que por aadidura prove servicios para que los programas puedan explotar al mximo estos recursos. Ahora bien, surge una duda interesante. Cmo se le hace para comunicarse con el sistema operativo? No es una pregunta ociosa. A final de cuentas, tanto hemos hablado de los servicios del sistema operativo pero no hemos dicho cmo obtenerlos. Pues bien, veamos. Estos servicios son, a final de cuentas, programas. Y como tal, son instrucciones estructuradas que se les da a una computadora. Pero estos servicios son genricos, as que tienen que estar disponibles para cualquier programa que quiera usarlos. Esto implica que, de alguna forma, que dichas instrucciones tienen que estar empaquetadas en algn lugar de nuestra computadora y en algn formato que permita que los otros programas puedan hacer uso de stas. Este problema se resuelve mediante las libreras. La analoga no podra ser mejor. En una librera uno encuentra libros. Cada libro tiene un contenido que lo hace nico y que tiene un propsito en particular: entretenimiento, artes, entretenimiento, etc. Las libreras de nuestro caso son similares: son en esencia, bloques de instrucciones (i.e. clases y subrutinas) que tienen un propsito en particular. Tambin son programas, pero son pasivos dado que no tienen un principio y un fin. Contienen cdigo y datos que proveen servicios a otros programas, y stos haran uso de las instrucciones que requieran, sin ningn orden en particular. Esto permite escribir cdigo de una forma modular. As, hablando de Windows por ejemplo, tenemos que la librera kernel32.dll prove los servicios del ncleo del sistema operativo, como el acceso a archivos, mientras que gdi32.dll provee todos los servicios relacionados con el manejo de grficos, y a su vez user32.dll contiene servicios relacionados con los usuarios, como las cuentas de sistema. Las libreras son usadas por los sistemas operativos para distribuir sus servicios, pero cualquiera puede crear una librera. Los compiladores modernos proveen esta capacidad, adecundose a las directrices de que el sistema operativo impone. Por ejemplo, la librera gl.dll 2 provee bloques de instrucciones para comunicarse con el hardware de vdeo y manipular grficos vectoriales, mientras que tapi32.dll provee servicios de telefona y comunicaciones. Cuando desarrollamos nuestros programas suele ser comn crear libreras para stos, sobre todo cuando tenemos varios programas que pueden compartir cdigo entre s. Como ves, podemos hacer uso de libreras en nuestros programas 3 . Para ello, los compiladores modernos hacen un proceso que se llama "enlazado", de lo cul se hablar en una seccin posterior. Las libreras son tiles y resuelven muchos problemas, pero tambin tienen puntos flacos. Quizs uno de los mayores problemas sea el llamado "DLL Inferno". Digamos que tenemos un programa A que usa la librera X. Existe tambin un programa B que usa la misma librera X, pero una versin anterior a la que usa el programa A. Al instalar el programa B, ste sustituye (sin darse cuenta) la versin de X nueva con la vieja. Boom! Lo ms seguro es que el programa A fallar. As que hay que ser cuidadosos con la forma en la que distribuimos nuetras libreras. En general, nos encontramos con que hay dos tipos de libreras: estticas y dinmicas. Tambin tenemos una tercera forma, las libreras de cdigo, pero su naturaleza es un tanto diferente a las dos primeras, debido a que no son programas compilados, sino simplemente cdigo fuente. Veamos. Libreras estticas Una librera esttica es un programa que consiste en una serie de bloques de instrucciones (rutinas) que son copiadas a nuestro programa al momento de que ste se compila (como se detalla en una seccin posterior). A este proceso se le conoce como "construccin esttica (o enlazado esttico) del programa". Durante la construccin, se obtienen datos como la ubicacin en la memoria de las rutinas y se "enlazan" con los llamados que nuestro programa hace de stas. Es como hacer un copy-paste automtico: el compilador "pega" a nuestro ejecutable todas las rutinas que contiene la librera. Este proceso tiene ventajas y desventajas, como todo en la vida. Las ventajas ms notables son las siguientes. No hay problemas relacionados con las versiones. Unos prrafos antes mencionbamos el problema de las DLL Inferno. Aqu no hay ese problema, puesto que, al ser la librera esttica enlazada con el programa, no hay riesgo de que otro programa sobreescriba algo. No hay dependencias. En efecto, por la razn anterior, tampoco se tiene que distribuir binarios extras, reduciendo la huella (footprint) de un programa a un solo archivo: el ejecutable. El enlazado se resuelve en tiempo de compilacin. Si el programa hace uso de la rutina X, y sta no se encuentra en la librera, el programa simplemente no compila. Son ms eficientes. Debido a que las rutinas se copian a nuestro programa, el sistema operativo no tiene que andar buscando los puntos de acceso para cada rutina llamada, cada vez que el programa haga uso de ellos, toda vez que esto se resuelve en tiempo de compilacin. Algunas de sus desventajas son: Gasto inecesario de espacio. Si un programa se enlaza con una librera, de la cul solo utilizar una que otra rutina, se puede desperdiciar una cantidad grande de espacio, ya que el compilador copiar todo lo que haya en la librera. Puede generar programas muy grandes. Si un programa enlaza con varias libreras, el tamao del mismo crecer en forma proporcional, por el mismo hecho de que copia todo su contenido. Redundancia de cdigo. Si dos programas hacen uso de la misma librera, sta se copiar para ambos, lo cul hace que se genere el mismo cdigo compilado dos veces. Problemas de mantenimiento. Cualquier cambio que se haga en una librera implica que el programa original tiene que recompilarse. Esto puede ser un problema cuando varios programas hacen uso de la misma librera. Es probable que haya ms ventajas y desventajas que se me escapen, pero creo que estas son las ms importantes. Libreras dinmicas Una librera dinmica (o de enlazado dinmico) sigue un concepto similar al de la librera esttica, en tanto que es un programa que contiene bloques de cdigo (rutinas o clases) a ser utilizados en nuestra aplicacin. Pero hasta ah llega la similitud. A diferencia de las libreras estticas, las libreras dinmicas se enlazan (imagnate) de forma dinmica. Esto es, las rutinas no se copian a nuestro programa, sino que solo se copian unas referencias conocidas como tablas de smbolos. Cuando nuestro programa es ejecutado, el sistema operativo carga estos smbolos y busca el programa que corresponde a la librera. Luego, busca dentro de la librera las secciones de cdigo que va a utilizar nuestro programa y las copia a su espacio de memoria, desde donde ya estarn disponibles las rutinas para que sean llamadas. El uso de libreras de enlazado dinmico, como todo en la vida, tienen sus ventajas y desventajas. Algunos de sus puntos buenos son: Espacio. Una librera dinmica se carga en tiempo de ejecucin, y puede ser cargada por varios programas al mismo tiempo, por lo que solo es necesario un solo archivo, al cul se pueden enlazar tantos programas como soporte el sistema operativo, con lo cul nos ahorramos el repetir el mismo cdigo, como con las libreras estticas. Rapidez al compilar. Dado que solo se tiene que guardar una referencia a los smbolos a enlazar en tiempo de ejecucin, la compilacin es ms rpida que con su contraparte esttica. Solo se cargan las porciones de la librera que se van a usar. Modularizacin. Permite separar el sistema en mdulos ms pequeos y fciles de mantener, an cuando no vayan a ser utilizados por otros programas. Esto tiene la ventaja de los vendedores pueden dividir sus sistemas en diferentes versiones, de acuerdo a la licencia que hayan comprado, y solo se tienen que limitar a distribuir las libreras adecuadas. Mantenimiento y distribucin. Al ser modularizado, se pueden distribuir actualizaciones slo a las libreras que las requieran, siempre y cundo no cambie la tabla de direcciones de la librera. Esto permite que en lugar de redistribuir todo el sistema solo se tenga que enviar la librera necesaria. A pesar de las ventajas que esto tiene, tambin tiene algunas serias desventajas, como las siguientes. Versiones. El reemplazar una versin nueva por una vieja suele tronar programas que requeran la librera ms reciente. Esto pasa cuando dos programas A y B hacen uso de la librera. Se instala A con la librera versin 2, y luego se instala el B que reemplaza la librera por la versin 1. A este problema se le llama "Inferno DLL" en el mundo de Windows. Ofuscacin del cdigo. A algunas personas les parece que el hecho de que el cdigo se encuentre "en algn otro lado" que no sea el propio programa puede hacer que el programador no sepa de dnde viene tal o cul funcionalidad. Yo digo que cualquier programador con poco seso para no saberlo merece que le pase todo lo malo que le puede pasar. Demasiadas dependencias. Similar al punto anterior. Si el programa hace uso de la librera A, sta de la B, y sta de la C, el programa necesitara redistribuir A, B y C. Y as sucesivamente, lo cul puede terminar generando muchas dependencias, que no es malo en s mismo, pero una exageracin de esto puede llevar a que se use una librera con dependencias cuya funcionalidad es poca, y es mejor reescribila en lugar de distribuir todo. Lmites de memoria. Un valor creado en la librera y que se pretenda acceder dentro del programa puede causar problemas de memoria, debido a que dicho valor estara "cruzando las fronteras de la librera", con direcciones de memoria diferentes debido a la memoria virtual (se explica esto ms adelante). Hay que estar atento a esto. Son inseguras por defecto. Bueno, ms o menos. Dado a que una librera dinmica carga su espacio de memoria dentro de otro, un hacker podra aprovechar alguna ranura para colarse y tener acceso al programa, y por ende a los datos que ste maneja, dando lugar a robo de informacin y otras malicias. Esto se puede evitar siguiendo ciertas tcnicas, que por defecto no se tienen. Las libreras dinmicas son muy utilizadas, a pesar de sus desventajas. En general, con buen uso de ellas, y un buen entendimiento de sus puntos fuertes y dbiles, se pueden escibir programas potentes y extensibles. Un ejemplo de esto es la arquitectura de los "plug ins" o "add ons", cuya lgica permite que se puedan escribir extensiones para un programa en particular. Un ejemplo un poco sofisticado de esto son los "add ons" que permite el Internet Explorer para aadirle funcionalidad. Libreras de cdigo Ya hablamos de las libreras estticas y de las dinmicas. Como complemento a estas, tambin podemos considerar como libreras al cdigo que de una u otra forma se distribuye tal cul, para ser includo (y compilado) por nuestros programas. En efecto, hay este tipo de libreras, las cules no son binarios, sino simple texto plano. Un ejemplo de esto es la famosa librera Boost 4 . Esta librera para C++ es distribuida casi en su totalidad por puro cdigo fuente que se incorpora de forma sencilla en nuestros programas (basta con hacer un #include, concepto que explicamos en otros captulos). Otro ejemplo es la Active Template Library, distribuida por Microsoft, y la Windows Template Library, construida sobre ATL 5 . Para qu distribuir el cdigo fuente como librera? Por necesidad. C++ tiene varias caractersticas que difcilmente se pueden "exportar" de una librera dinmica (como las plantillas 6 ), y aunque varios compiladores pueden empaquetarlas en libreras estticas, el cdigo fuente (al menos el de la definicin) tiene que ser distribuido de cualquier forma. As, muchas veces se opta por distribuir el cdigo necesario y listo. Modularidad. Las libreras estticas empotran su contenido en nuestro programa. Las libreras dinmicas se enlazan con nuestro programa y solo cargan lo que necesitan, pero se distribuye con toda la funcionalidad, an si no la ocupamos. En algunos casos donde solamente vayamos a emplear una pequea funcionalidad, es ms conveniente copiar el cdigo que vamos a utilizar y listo, no problemos. Didctica y depuracin. Hay veces en que los creadores de la librera prefieren que sea el programador quien revise el cdigo para que entienda qu es lo que hace, y pueda aprender de ah. O bien, para que los depuradores puedan mostrar algn comportamiento, paso a paso. Algunas libreras, como MFC, proveen el cdigo fuente (adems del binario) por si alguien tiene dudas y para que el compilador pueda hacer su trabajo sin problemas. Sin embargo, es una forma nada efectiva de proteger nuestro cdigo. Adems, tambin puede ocasionar problemas con respecto a versiones, si no se tiene cuidado. A final de cuentas, todo depende de cmo te sientas ms cmodo. Las tres formas tienen sus ventajas y sus desventajas, y finalmente lo que cuenta es la calidad del desarrollo y la administracin del proyecto para evitar andar cometiendo errores. Cualesquiera de los tres modelos presentados pueden ser muy buenos o muy malos, dependiendo ultimadamente de t. Interfaz de Programacin de Aplicaciones Si ya llevas algn tiempo programando, seguramente habrs escuchado la palabra API en algn lugar. Y si no, te digo de una vez que API probablemente es una de las palabras ms empleadas en el argot de la programacin, ms incluso que la "C" de C++. En realidad, API no es una palabra, sino un acrnimo para Application Programming Interface, o Interfaz de Programacin de Aplicaciones. Qu hay detrs del nombre? Vayamos por partes. Dice que es una interfaz. A qu se refiere? sta es una de esas palabritas que se usan en muchos lados con significados distintos, algo similar a lo que le pasa a la palabra "mdulo". En general, una interfaz es una especie conexin entre dos entidades, con una funcionalidad bien definida. Pensemos en un televisor. ste tiene una serie de botones que hacen algo: cambiar de canal, subir de volumen o ajustar el color. so es una interfaz, ya que nos permite interactuar con el aparato y por ende nos "conecta" con l. Ahora bien, es una interfaz de programacin. La programacin es el acto de escribir programas, o sea, escribir instrucciones de forma estructurada. As pus, cuando hablamos de que un API es una interfaz de programacin, nos referimos a que es un conector para poder programar. Ms precsamente, es un conector entre nuestro programa y algn otro programa ya existente. Un conector para desarrollar aplicaciones. Es decir, un API es un conjunto de especificaciones para que nuestra aplicacin pueda acceder a los servicios que proporciona otro programa, tpicamente una o varias libreras. El API que el sistema operativo expone para obtener sus servicios es uno de los ejemplos clsicos de APIs, pero no el nico. Pero qu diferencia tiene con una librera? Bueno, en primera un API puede hacer uso de una o ms libreras. Por otro lado, las APIs se escriben pensando en que otros programadores las utilizarn, mientras que las libreras se escriben pensando en resolver un problema en particular. Por ejemplo. Supongamos que creamos un programa X y queremos que otros programas puedan obtener datos del nuestro o interactuar con ste. Le tenemos que exponer una forma en la que pueda leer los datos o invocar alguna accin. En primera, podemos crear una librera que exponga algunas rutinas, digamos una para leer el nombre del usuario que ha ingresado al programa. El programa externo se enlaza a la librera dinmica y manda llamar a la rutina y obtiene el nombre, y hace lo que tenga que hacer. Pero nuestra rutina seguramente har muchas otras cosas antes de regresar el resultado. Estas otras cosas no es necesario exponerlas y son privadas a la librera. En este caso, ya tendramos nuestra API: las rutinas necesarias para llevar a cabo una tarea, a travs de una interfaz. Las APIs suelen tener las siguientes caractersticas, con respecto a su distribucin. Nadie fuera del grupo creador conoce la informacin del API. Esto suele suceder cuando el API estar disponible para otros programas de la misma compaa, por lo que el pblico general no debe tener acceso a ella. La informacin del API puede estar licenciada y se protege del pblico en general. Algunas compaas siguen este modelo para poder obtener mayor calidad, al controlar quin emplea el API. Cualquiera puede acceder al API, al estar disponible de forma gratuita. Cuando se quiere motivar a que otros programas usen nuestros servicios, en aras de promover nuestra tecnologa, se suele usar este modelo (i.e. el API de Windows). En fin, que hay APIs para todo. Y va un poquito ms all del concepto de librera: como se ha dicho, el API suele ser un conjunto de libreras. La memoria En la seccin anterior, tratamos de explicar lo que era un programa, mencionamos algunos tipos de programas y dibujamos de forma un poco general cmo est compuesto un programa. Un componente indispensable para cualquier programa es la memoria. No hablamos de sta en la seccin anterior debido a que es un componente de hardware, no de software, adems de ser un tema lo suficientemente extenso e importante como para tratarlo en una seccin aparte. sta es dicha seccin. La memoria es uno de esos conceptos que todos conocemos pero que rara vez comprendemos bien. Seguramente has oido decir que tal programa necesita tantos megabytes de memoria para funcionar, o que el archivo equis ocupa tantos gigabytes de disco duro. Con frecuencia, le gente se transfiere archivos mediante memorias USB o copia sus 4 gigabytes de msica en un DVD. Todos estos conceptos utilizan el trmino "memoria", ya sea de manera explcita (RAM, disco duro) o implcita (USB, DVD). Pero estos conceptos pudieran parecer inconexos entre s. A qu nos referimos cuando hablamos de memoria? En pocas palabras y a nivel general, nos referimos al almacenamiento de informacin. As es. A final de cuentas, cuando hablamos de memoria, hablamos de dispositivos de almacenamiento de informacin. No en vano el nombre de memoria: viene a ser un smil, en el cul el dispositivo pretende "recordar" valores previamente establecidos. Pero a ver, mencion que la memoria "guarda" informacin. Cmo la guarda? O mejor an: qu es lo que guarda? Comencemos por enterarnos qu es lo que se quiere guardar antes de preocuparnos cmo se guarda. Datos S, s, s, hemos hablado de datos. Qu demonios es un dato? En cuanto a computacin se refiere, a nivel general un dato es cualquier cosa que se pueda usar con una computadora. Qu explicativo, verdad? Vale, vale. Fundamentalmente, un programa es un conjunto de instrucciones estructuradas, como se explic en la seccin anterior. Pero eventualmente un programa tiene que hacer algo: por poner un ejemplo sencillo, una suma. Mi programa necesita saber cules son los sumandos para poder operar y regresar el resultado. Los dos sumandos son valores numricos que obtuvimos de alguna forma (digamos, el usuario lo proporciona al programa). Esos dos valores numricosson datos. No son valores prestablecidos, sino que se generan con el transcurrir del programa. As pues, cualquier cosa que sea manipulada por nuestro programa la denominaremos con el nombre de dato, a secas. Una computadora representa datos usando un sistema numrico binario: texto, nmeros, imgenes, audio, vdeo y cualquier otra forma de informacin se reduce a un conglomerado estructurado de bits (dgito binario, binary digit), que puede tener un valor de un 1 o un 0. Este conglomerado normalmente se almacena en una unidad comn denominada byte, que usualmente consiste en ocho bits. A final de cuentas, las mquinas solo entienden nmeros 7 , y --diga lo que diga mi padre-- el sistema numrico ms sencillo es el binario, que contiene slo dos dgitos. Vamos paso a paso. Sistema numrico binario El sistema numrico binario moderno fue documentado por primera vez por uno de mis hroes, el alemn Gottfried Leibniz, en su artculo Explication de l'Arithmtique Binaire en el siglo XVII. Leibniz us el 1 y el 0 como los dos componentes numricos del sistema, y se bas en trabajos anteriores para dar una explicacin somera al respecto. Pero no sera hasta 1854 cuando otro de mis hroes, el britnico George Boole public su libro An Investigation of the Laws of Thought, donde detall un sistema algebrico para la lgica, que posteriormente sera conocido como lgebra booleana. Un nmero binario no deja de ser un nmero natural, por lo que se le pueden aplicar todas las operaciones definidas para los nmeros naturales, como la suma y la multiplicacin 8 . As, podramos realizar la siguiente operacin: decimal: 5 + 7 = 12 binario: 101 + 111 = 1100
decimal: 5 * 7 = 35 binario: 101 * 111 = 100011 Pero lo interesante en este caso son las operaciones descritas por Boole: conjuncin, disyuncin y negacin. Estas operaciones estn basadas en sus contrapartes lgicas. Una conjuncin es verdadera si los dos elementos son verdaderos, y falsa en los dems casos. Una disyuncin es verdadera si alguno de los dos elementos es verdadero, y falsa si ambos son falsos. Una negacin es verdadera cuando el elemento es falso, y es falsa cuando el elemento es verdadero. Ahora, sustituyamos los trminos "verdadero" y "falso" por "1" y "0", y listo. Las operaciones se hacen a nivel de elementos. conjuncin: disyuncin: negacin: 100110 100110 010101 010101 100110 -------- -------- -------- 000100 110111 011001 Tambin se pueden interpretar nmeros negativos, haciendo la negacin de todos los dgitos y sumndole un uno. Por ejemplo: 35 => -35 00100011 => 11011100 + 1 = 11011101 Dado que el binario es un sistema de base 2, cada dgito representa un incremento en potencia de 2, donde el dgito que se encuentra ms a la derecha representa a 2 0 , el siguiente 2 1 , el que le sigue 2 2 , etc. Esto introduce otro tipo de operacin que suele ser utilizada: el desplazamiento de dgitos a la derecha y a la izquierda. En general, esto quiere decir que los dgitos son "desplazados" una posicin (a la derecha o a la izquierda) y el nuevo lugar se sustituye por un cero. Si suponemos que "<<" representa el operador de desplazamiento hacia la izquierda, y ">>" hacia la derecha, tendramos las siguientes operaciones: desplazamos 3 dgitos a la izquierda 38 << 3 = 304 (38 * 2 3 ) 100110 << 3 = 100110000
desplazamos 3 dgitos a la derecha 38 >> 3 = 4 100110 >> 3 = 000100 Estas operaciones podran no tener sentido ahorita, pero ms adelante en este tutorial retomaremos el tema y mostraremos algunas de sus aplicaciones. Bits, bytes y palabras La palabra "bit" es la contraccin de "binary digit", y como tal significa dgito binario. Es decir, los bits no son otra cosa que los nmeros binarios de los que hablbamos hace un momento. Sin embargo, un bit por s solo no representa nada: es solo un dgito y ya. As pues, no podemos decir que un bit tenga un significado, y por lo tanto un bit no lo podemos considerar como un dato. Los bits tienen sentido solo cuando los agrupamos. Hay varios tipos de agrupaciones de bits, con nombres propios, pero tradicionalmente se considera al byte como la agrupacin mnima de informacion; es decir, el byte es la unidad mnima de un dato. Un byte suele contener 8 bits. De ah que un byte puede representar cualquier nmero entre el 0 y el 255 (00000000 al 11111111). Fuera de los bytes, podemos agrupar nuestros bits de cualquier forma que queramos. Una agrupacin que se suele hacer es la conocida como "palabra", y sus derivados como la palabra doble(dos palabras) y la palabra cudruple (cuatro palabras). El nmero de bits por palabra suele variar, y en particular est ligada al concepto de direccin de memoria de los sistemas operativos (de lo cul hablaremos un poco ms adelante). Por ejemplo, en sistemas operativos de 32 bits como Windows XP, las palabras suelen ser agrupaciones de 16 bits (pudiendo almacenar valores numricos entre 0 y 65535, es decir, 0 y 1111111111111111), y por ende la palabra doble tendra 32 bits y la cudruple 64 bits. Las palabras cumplen una funcin muy especfica dentro del sistema operativo. Si bien la unidad mnima de informacin suele ser el byte, normalmente la unidad mnima de procesamiento es la palabra. Es decir, el procesador "procesa" instrucciones por palabra (en Windows XP, por ejemplo, en bloques de 16 bits). Interpretacin de los bytes Ahora bien, anteriormente dijimos que un dato podra ser un texto, una imagen o un vdeo. Y tambin dijimos que un dato no era otra cosa que un conjunto de bits, usualmente agrupados en bytes (ocho bits). Luego entonces un texto, una imagen o un vdeo es un conjunto de bytes. Cmo es que sucede esto? Cmo es que el vdeo que baj de YouTube hace media hora es un conjunto de bytes? Como dijimos, la mquina solo conoce nmeros (bits). Lo importante aqu es la interpretacin que se les da a esos nmeros. En efecto, mientras que la mquina lee los nmeros, el hardware se encarga de interpretar esos nmeros y hacer algo con ellos. Por ejemplo, el monitor. ste dispositivo muestra puntitos de colores, que en conjunto muestran una imagen. El sistema operativo utiliza un byte para cada color (en el caso del sistema RGB). As, si el primer byte tiene valor 255, y el segundo y tercero valen 0, el monitor interpreta estos valores y muestra un rojo para la celda especificada (a travs de otros dos nmeros que representa la coordenada cartesiana dentro del monitor). La computadora nunca dej de manejar nmeros, pero el monitor los interpret de cierta forma y produjo un resultado. As es con el resto de las cosas, aunque no tan sencillo como lo descrito aqu. Sin lugar a dudas, hacer todo este tipo de interpretaciones tiene sus complejidades. En los das antes de Unix, todo lo que se poda utilizar eran las palabras. Hacer la interpretacin para tal o cul byte llevaba tiempo y poda conducir a errores. Por ello, se pens en alguna forma de codificar e interpretar los bytes. De aqu surje el concepto de tipo de dato. Un tipo de dato no deja de ser un conjunto de bits. Pero este conjunto tiene una particularidad muy especial. En primer lugar, estn agrupados por bytes. En segundo lugar, se pueden utilizar valores alternativos ms legibles para los humanos y que la mqiuna los interprete y haga la interpretacin de forma automtica. Y en tercer lugar, hace ms difcil mezclar tipos de datos no relacionados entre s, y detectar estos errores en la fase de desarrollo del programa. Por ejemplo, un tipo de dato nmero entero. ste representa a los nmeros enteros (naturales ms los negativos de los naturales). Podemos decidir que este tipo de dato tenga dos bytes, de tal suerte que se puedan guardar valores numricos cuyo rango vaya de 0 a 65536. Ahora, tambin queremos guardar valores negativos, por lo que nuestro rango lo tendramos que manejar desde -32767 hasta 32768. Nuestro tipo de dato hara la interpretacin propia en cada caso, negando los bits cuando se trate de un nmero negativo, etc. Hacer esto nos salvara de tener que hacer las interpretaciones propias. Podemos crear diferentes tipos de datos, como por ejemplo un caracter, de un byte, cuyo valor numrico represente una letra del alfabeto; o un tipo de dato que permita manejar decimales, que interprete el punto decimal con un bit especial. Lo interesante de esto es que los lenguajes de programacin modernos normalmente definen tipos de datos estndares. De esta forma, al compilar nuestro programa se genera en automtico la interpretacin de los bytes, y ya no nos tenemos que preocupar ms por el asunto. Los tipos de datos son centrales en C++, y los exploraremos ms en otros captulos. Almacenamiento Dejemos el concepto de dato a un lado por el momento, toda vez que ya tenemos una nocin de qu es lo que se va a guardar en la memoria. Pasemos a ver cmo es que se guarda. La memoria es un dispositivo de almacenamiento de datos, que permite retenerlos por un intervalo de tiempo determinado. Estos dispositivos son elementos bsicos de una computadora, e implementan una computadora bsica junto con la unidad central de procesamiento (CPU). Existen diferentes tipos de almacenamiento de datos que han sido inventados hasta la fecha. Su naturaleza vara mucho dependiendo del contexto histrico de cuando fue inventado, as como el problema particular que intentaba resolver. An hoy en da no se ha podido crear alguna forma universal, y como todo en la vida, cada tipo de almacenamiento tiene sus desventajas con respecto a los otros. Lo que nos interesa guardar son datos. Y los datos, ya vimos, son agrupaciones de bits. El cmo los guardemos carece de importancia, a menos que te interese saber cmo funciona el hardware. Pero hay muchas formas de guardarlos. De hecho, podemos hacer varios tipos de clasificaciones de los dispositivos de almacenamiento, dependiendo de su jerarqua, su volatibilidad, su mutabilidad, su accesibilidad, su capacidad y el tipo de dispositivo sobre el cul operan. Jerarqua de la memoria Los dispositivos de almacenamiento funcionan alrededor de la unidad central de procesamiento (CPU). De acuerdo con esta unidad, podemos hacer una jerarqua de dispositivos dependiendo de cmo son tratadas por la CPU. Usualmente reconocemos hasta tres tipos de jerarquas, creativamente nombradas como primaria, secundaria y terciaria. El dispositivo primario de almacenamiento (usualmente referido como "La Memoria") es, evidentemente, la memoria principal y es la nica directamente accesible desde el CPU. ste contnuamente lee las instrucciones ah almacenadas y las ejecuta conforme lo va requiriendo. Cualquier dato que est siendo utilizado y operado tambin es almacenado ah. Hoy en da, este dispositivo primario suele ser la memoria de acceso aleatorio (random access memory, RAM), la cul es ligera y voltil (esto es, que pierde los datos almacenados cuando no est alimentada por energa elctrica). Adicionalmente, el dispositivo primario suele tener dos sub-capas. El registro del procesador, que se encuentra dentro del mismo, suele contener un conjunto de palabras, donde se guardan valores que suelen ser utilizados con frecuencia, y por ende son ms rpidos de accesar (por estar dentro del CPU); y el cach del procesador, que es un sector intermedio en donde se puede ir pre-procesando las instrucciones para drselas "digeridas" al CPU. Los dispositivos secundarios de almacenaimeinto difieren de los primarios en tanto que no pueden ser accesados por el CPU. En lugar de utilizar buses de comunicacin, se utilizan canales de entrada y salida (Input/Output, I/O) para comunicarse, y utiliza sectores del dispositivo primario para transmitir la informacin. A diferencia del dispositivo primario, el secundario suele ser no voltil (es decir, no se pierde la informacin una vez que se desconecta). Pero por lo mismo, suele ser ms lento almacenar datos ah. Hoy en da, este dispositivo secundario suele ser uno o varios discos duros, aunque puede darse el caso de que haya otros, como memorias flash (i.e. USB), discos floppy o dispositivos ZIP. Los dispositivos terciarios de almacenamiento proveen una tercera opcin de almacenamiento, y usualmente son dispositivos que se montan y desmontan a peticin del usuario o de la mquina, de tal suerte que su presencia o ausencia en la computadora no afecta el funcionamiento de la misma. CD-ROMs, CD-RW y unidades DVD suelen ser un ejemplo muy comn. Volatibilidad Independientemente de la jerarqua de la memoria en cuestin, podemos hacer varias clasificaciones del dispositivo de almacenamiento. La volatibilidad es una de esas caractersticas. Una memoria es voltil si pierde la informacin guardada cuando se le corta la corriente elctrica. Esta memoria tiene que ser inicializada cada vez que se utiliza, tpicamente cuando se prende la computadora. En contraste, la memoria no voltil es aquella que persiste incluso despus de ser desconectada. La memoria voltil tiene la ventaja de que, al no requerir persistir los datos, no necesita recursos para ello y por ende es ms rpida. La memoria primaria, que neceista rapidez ms que otra cosa, usualmente es voltil (como la memoria RAM), mientras que las memorias para almacenamiento persistente suelen ser no voltiles (como discos duros). Diferenciacin La diferenciacin se refiere a memorias voltiles cuyo contenido puede cambiar sin previo aviso. As, tenemos dos clasificaciones, de acuerdo a este trmino. La memoria dinmica (Dynamic RAM, DRAM) es una memoria voltil que requiere que cualquier informacin almacenada sea refrescada (leda / escrita) constantemente, so pena de que se pierda dicha informacin. La memoria esttica (Static RAM, SRAM) es memoria voltil que no necesita refrescarse peridicamente. La ventaja de la DRAM es la sencillez de su estructura a nivel de hardware. Existen muchas variaciones de la DRAM, como la SDRAM (Single Data Rate RAM), que es una forma sncrona de la DRAM; o la DDR RAM (Dobule Data Rate RAM), que se comenz a emplear mucho a partir del ao 2000. Mutabilidad La mutabilidad hace referencia a la capacidad de una memoria para cambiar su contenido. Hay tres posibles variantes. Almacenamiento totalmente mutable. Permite que la informacin pueda ser reescrita en cualquier momento. Las memorias de almacenamiento principal (memoria RAM) suelen tener este tipo de mutabilidad; de otra forma, seran totalmente intiles para la mayora de las tareas que el CPU le encomienda. Almacenamiento inmutable. Retiene la informacin guardada al momento de ser manufacturada, permitiendo que la informacin pueda ser guardada solo una vez, la primera. Estos son llamados almacenamientos inmutables, y suelen ser dispositivos de almacenamiento terciarios como CD-ROM y DVD-ROM. Almacenamiento de escritura lenta y lectura rpida. Permiten que la memoria sea sobreescrita en mltiples ocasiones, pero la escritura de los datos es mucho ms lenta que la lectura. Ejemplos, son los CD-RW o DVD-RW. Accesibilidad La accesibilidad es la capacidad de una memoria de acceder a sus datos. Hay dos tipos de memoria, de acuerdo a este criterio: las de acceso aleatorio y de acceso secuencial. El acceso aleatorio (acceso directo) es la habilidad de acceder a un elemento arbitrario dentro de una secuencia, en tiempo real. El acceso secuencial es lo contrario, donde se va uno por uno, de principio a fin, hasta llegar al elemento deseado. El acceso aleatorio implica la habilidad de que acceder a la n-simo bloque de memoria es constante en tiempo. Este tipo de comportamiento es crtico para el funcionamiento de una memoria primaria, ya que acelera el procesamiento del CPU. El acceso secuencial no provee esta ventaja, pero a veces es la nica forma de acceder a la memoria (por ejemplo, en alguna cinta magntica). Direccionamiento El direccionamiento hace referencia a la capacidad de la memoria para especificar dnde se encuentra un bloque de memoria determinado, proveyendo una suerte de direccin del bloque. Hay tres clasificaciones: direccin por localizacin, direccin por archivo y direccin por contenido. En el direccionamiento por localizacin, cada unidad individual de informacin almacenada es seleccionada a travs de un valor nmerico llamado direccin de memoria. En las computadoras modernas, el almacenamiento por localizacin usualmente se limita al dispositivo de almacenamiento primario, accesado internamente por los programas, toda vez que la localizacin por direccin de memoria es muy eficiente, pero poco intuitiva para el humano comn. En el direccionamiento por archivo, cada bloque de informacin est dividido en archivos de longitud variable, y un archivo particular es seleccionado dado un directorio y nombre. Bajo el agua, el directorio del archivo se mapea con una direccin de memoria, pero el sistema operativo de la computadora provee una abstraccin para hacer la operacin ms entendible. Dispositivos secundarios y ternarios como los discos duros y las memorias USB suelen tener este tipo de direccionamiento. Finalmente, en el direccionamiento por contenido, cada unidad de informacin es seleccionada individualmente en base a una estructura denominada "hash", en la cul un valor es accedido por una clave. Cada bloque de memoria tiene asignado un identificador numrico, y se accede a travs de l. La diferencia es que no es una seccuencia de nmeros, sino que los valores pueden ser aleatorios. Notas 1. Ralph M. Stair et. al. (2003). Principios de Sistemas Informticos, 6a Edicin, Thomson Learning, Inc.. pp. 132. ISBN 0-619-06489-7. 2. OpenGL, www.opengl.org. 3. A pesar de que las libreras son algo comn, por no decir necesarias, en el desarrollo de software, este tutorial no mencionar cmo crearlas. Esto es debido a que no forman parte del estndar C++, y por tanto son especficas de cada sistema operativo, y de hecho varan entre ellos. 4. www.boost.org. 5. ATL y WTL. 6. Ver el captulo de plantillas. 7. Que dicho sea de paso, a nivel de hardware se traducir en bloques de electrones con diferentes voltajes. corriente elctrica altera. 8. No es propsito de este tutorial ensear el sistema binario ni cmo hacer las operaciones ni cmo convertir un nmero decimal a uno binario. Sin embargo, la forma ms fcil de hacer esto es empleando la calculadora de Windows en modo cientfico. Por ejemplo, puedes escribir el nmero 7 y luego hacer click en la casilla que dice "Bin" y se convertir en la representacin binaria 111. Comentarios Acceder|Informar de uso inadecuado|Imprimir pgina|Eliminar acceso|Con la tecnologa de Google Sites