Práctica 2: Realización de una Alarma Temporizada Diseño de Sistemas Operativos U.L.P.G.C.

Tamaño: px
Comenzar la demostración a partir de la página:

Download "Práctica 2: Realización de una Alarma Temporizada Diseño de Sistemas Operativos U.L.P.G.C."

Transcripción

1 Práctica 2: Realización de una Alarma Temporizada David Jesús Horat Flotats

2 Índice I. Explicación del Programa desarrollado... 2 Programa Principal... 2 Variables Tarea que realiza Parámetros Movimiento de la bola Señales... 9 Alarma (en Tiempo Real) Interrupción Lanzamiento de Procesos...12 Uso de fork Uso de exec Uso de waitpid Uso de exit Control de la Sección Crítica, con Pipes...16 Definición de Pipe Manejo de Pipe Problema de la Sección Crítica Solución a la Sección Crítica II.Compilación y Ejecución del programa (Makefile)...20 Explicación y Reglas del Makefile Ejecución del programa Paso de Parámetros III.Anexo Código Fuente...28 alarma.c...28 Makefile

3 Explicación del Programa desarrollado Programa Principal Variables Las variables definidas son de dos tipos fundamentales: globales y locales a la función main. La utilidad de las variables globales radica en el hecho de que serán usadas por funciones a las que se llama en el momento de producirse las señales, como la alarma, de modo que no pueden pasarse por parámetro. Las variables globales son las siguientes: 1. Tubería para el control de la concurrencia, mediante el uso de pipes (int tuberia[2]). 2. Tiempo de duración de la alarma (int tiempo_alarma = 4). Las variables locales son las siguientes: 1. Variables para controlar el movimiento de la bola: 1. Columna inicial, en la que empieza la bola (int columna = 0). 2. Columna máxima a la que puede llegar la bola (int max_columna = 40). 3. Paso, que indica el número de columnas que avanza la bola en cada iteración de muestreo de la misma (int paso = 1). 4. Velocidad de la bola, que se controla con el número de iteraciones de un bucle, de modo que mientras menor sea el valor de esta variable mayor será la velocidad y viceversa, aspecto que debe tenerse en cuenta al asignarle un valor (int velocidad = ). 2. Variable para tomar el valor de las lecturas y escrituras de las tuberías (int valor). 3. Variable para la realización de iteraciones, y tareas auxiliares (int i). 4. Indicación de señales creadas (int senal_creada = 0;). 5. Ristra que representa la bola (char *bola = "o";). 6. Estructuras de las señales para la implementación con SIGACTION (struct sigaction senal_alarma, senal_int;). Se puede observar que la mayoría de las variables son inicializadas en el momento de su definición, de modo que así se tendrán valores por defecto para las mismas. 2

4 Tarea que realiza El programa principal hará un uso intensivo de la salida por pantalla. Para ello se hace uso de la función printf. El uso de esta función obliga a incluir la librería <stdio.h>. Una alternativa al uso de las funciones de la librería stdio es el uso de librerías especiales para el manejo de la impresión en el terminal. Destacan las librerías conio y ncurses. La librería ncurses es amplísima y de gran utilidad para el manejo del terminal de Linux y la impresión de cadenas de caracteres en el mismo. El problema de la librería ncurses, que se incluiría en nuestro programa como <curses.h>, es que maneja una pantalla propia, distinta a la que usa la función printf. Hasta aquí no hay problema, pero si se usa la función printf a la vez que se emplean función de la librería ncurses, como move y addch, una pantalla moverá a la otra y el resultado será desastroso; además, da un aspcto de concurrencia incontrolada, del todo indeseable para cualquier programa serio. Finalmente, la salida del programa para imprimir por pantalla se hará con la función printf. El programa desarrollado imprimirá en pantalla un bola que se moverá rebotando de derecha a izquierda, en una línea de la pantalla; sin tener en cuenta el efecto que tendrá el muestreo de la fecha, hasta que se introduzca ésta con la alarma. En realidad, se hará una emulación de la bola con un carácter. No obstante, el programa permitirá que dicha emulación de la bola pueda ser incluso una ristra de cualquier dimensión (en principio mayor que la unidad, es decir, que al menos sea un carácter). El programa principal main realizará una serie de tareas principales o pasos, que se indican y comentan a continuación: Paso 1: Parámetros de entrada El programa principal, una vez compilado y construido, en el momento de ejecutarse permitirá la rececpción de parámetros desde el terminal, para que la configuración del misma sea mayor y más flexible. De este modo la función main tiene la forma: int main(int argn, char *argv[]) { Estos parámetros permiten el control sobre aspectos como el carácter o ristra a usar para emular la bola, el número de columnas por el que se moverá ésta, el tipo de implementación para las 3

5 señales, el tiempo de duración de la alarma para imprimir la fecha y la velocidad de la bola (medida en iteraciones de un bucle). Todos los parámetros se explican en detalle en el apartado Parámetros. Paso 2: Inicializaciones Una vez se han tomado todos los parámetros, si es que se han introducido éstos, se procederá a la inicialización de determinadas variables y señales. En el caso de no indicarse ciertos parámetros, se usarán valores por defecto. En el caso de las señales, se usará la implementación con la función signal, por defecto, de modo que debe hacerse explícitamente se no se indica nada. // Si no se han creado las señales, se usa SIGNAL por defecto if (!senal_creada) { signal(sigalrm, muestra_fecha); signal(sigint, termina); Puede verse como se usa la variable senal_creada, que se inicializa a 0: int senal_creada = 0; // Indica si se han creado las señales Si se indica algo por parámetros se pondrá a 1, de modo que no se tendrá que hacer uso de la inicialización por defecto; este paso, en el código, se encuentra antes de la inicialización, porque en ocasiones es necesario y en otras no, en función de los parámetros de entrada. else if (strcmp(argv[p],"-s") == 0) { // Tipo de implementación de señales senal_creada = 1; En las inicializaciones propiamente dichas, se hacen dos tareas: crear e inicializar la tubería o pipe, para el control de la concurrencia (sección crítica) y activar la alarma. // Creación e inicialización del pipe pipe(tuberia); write(tuberia[1], &valor, sizeof(int)); fflush(null); // Alarma alarm(tiempo_alarma); Paso 3: Bucle de muestreo de la bola Se trata de un bulce infinito en el que se estará controlando el muestreo de la bola y que en cada iteración del bucle la bola se moverá una posición, por lo general una columna. while(1) {/*...*/ 4

6 Paso 3.1: Pausa entre movimientos de la bola Para que el movimiento de la bola sea más realista, tiene un control de velocidad con un bucle con un número de iteraciones controlado por la variable velocidad. for(i=0; i<velocidad; i++); No se usa la función sleep porque sólo admite segundos y en tal caso perdemos precisión. Pero además, y fundamentalmente, porque con esta función se dormiría el proceso y se le desasignaría la CPU, lo cual no nos interesa. Paso 3.2: Mover bola (controlando sección crítica con pipe) Para mover la bola se hará uso de la función printf imprimiendo cada carácter, que podrá ser espacios blancos o la propia bola, contenida en la variable bola. Este proceso se realiza controlando la sección crítica con los pipes. Para ver como se realiza el movimiento de la bola, basta dirigirse al apartado Movimiento de la bola. Paso 3.3: Actualizar posición de la bola Tras realizar el movimiento de la bola, que se controla fundamentalmente con la variable columna, se actualiza el valor de esta variable y así en la siguiente iteración se pinta la bola en la columna apropiada. La forma en que se realiza dicha actualización se explica en el apartado Movimiento de la bola. Parámetros El nombre asignado al programa desarrollado es alarma, de modo que se ejecturá escribiendo./alarma desde el terminal. Sin embargo, también admite parámetros, pues se declara la función main de la siguiente forma: int main(int argn, char *argv[]) { Los parámetros a pasar al programa se indicarán mediante identificadores del tipo de parámetro y su valor, de la foma: -TIPO_PARAMETRO VALOR_PARAMETRO. De este modo, el número de parámetros es par, pero como los argumentos que se reciben incluyen al propio nombre del programa, serán impares. Si no fueran impares, se debería a algún error, o bien a que se 5

7 pasa la opción --help, que es la ayuda, que indica como usar el programa, en cuanto al modo en que se le deben pasar los parámetros: if ((argn == 2) && (strcmp(argv[1],"--help") == 0)) { printf("modo de empleo:./alarma [OPCIÓN]\n"); printf("\t-b bola; Ristra que representa la bola\n"); printf("\t-c columna_máxima; Columna máxima a la que llega la bola\n"); printf("\t-s SIGNAL SIGACTION; Implementación de señales (SIGNAL por defecto)\n"); printf("\t-t segundos; Tiempo entre muestreo de la fecha\n"); printf("\t-v iteraciones; Velocidad de la bola\n"); exit(0); Las opciones serán, por tanto, las siguientes: -b bola --> Ristra que representa la bola; si tiene espacios o caracteres especiales debe ponerse entre comillas dobles. Se contendrá en la variable char *bola = "o";, que por defecto valdrá "o". -c columna_máxima --> Columna máxima a la que llega la bola, que será de tipo entero. Se contendrá en la variable int max_columna = 40;, que por defecto valdrá 40. -s SIGNAL SIGACTION --> Indica el tipo de implementación de las señales, que puede ser SIGNAL o SIGACTION. Según su valor se hará uso de una u otra implementación, y por defecto SIGNAL. -t segundos --> Tiempo entre muestreo de la fecha, medido en segundos, que es la duración de la alarma. Se contendrá en la variable global int tiempo_alarma = 4;, que por defecto tiene el valor 4. -v iteraciones --> Indica la velocidad de la bola, pero indicando el número de iteraciones, de modo que su valor es inversamente proporcional a la velocidad de la bola. Se contendrá en la variable int velocidad = ;, que por defecto vale Si el número de parámetros es erróneo y no se trata de la opción --help, se tendrá un error. if ((argn%2) == 0) { printf("alarma: Forma de uso incorrecta\n"); printf("pruebe:./alarma --help\n"); exit(0); Para tomar los parámetros, se hará uso de un bucle, en función del número de parámetros, iterando la mitad de ellos, pues uno dice el tipo y otro el valor. 6

8 int p; for(p=1; p<argn; p=p+2) { Esto es necesario porque se desconoce el orden de los parámetros. Para cada uno de los parámetros indicados se comprobará el tipo y luego se tomará su valor. Si se pusiera un mismo parámetro más de una vez, se tomaría el valor de la última. En el caso de la indicación de la implementación de las señales es obligatorio indicarlo, de modo que si no se hace, por defecto se usa la implementación SIGNAL, como ya se vio con anterioridad. Del mismo modo, si se indica dos veces, sólo se toma la primera, para no crear conflictos con una doble declaración de las señales. Como ejemplo podemos ver cómo se identifica el parámetro indicador de la ristra que emula la bola, mientras que el resto de parámetros pueden verse en el apartado alarma.c. if (strcmp(argv[p],"-b") == 0) { // Ristra que representa la bola bola = argv[p+1]; Movimiento de la bola Para move la bola, con la función printf, realizaremos todo el proceso del movimiento de la misma dentro de la sección crítica, controlada por los pipes, que se comentan en el apartado Solución a la Sección Crítica. Aquí pasamos a comentar simplemente como se realiza el movimiento de la bola para que dé la sensación de movimiento y que rebota al llegar a los bordes. El movimiento que hará la bola consiste en estar situada en una fila cualquiera y se moverá por las columnas de la misma. En principio se moverá desde la columna 0 a la columna máxima definida en la variable max_columna, que por defecto vale 40. Para simular este efecto sin salirnos de las columnas ni saltar de la línea, se usará el siguiente algoritmo para cada iteración: printf("\r"); for(i=0; i<columna; i++) printf(" "); printf(bola); for(i=columna; i<max_columna; i++) printf(" "); Lo primero es situarnos al inicio de la fila, en la columna 0, con la instrucción printf("\r");. A continuación se realizan 3 pasos bastante sencillos: 7

9 1. Dibujar espacios blancos antes de la posición de la bola. for(i=0; i<columna; i++) printf(" "); 2. Dibujar la bola. printf(bola); 3. Dibujar espacios blancos después de la bola pero antes de la columna máxima, lo cual funciona incluso para bolas que se simulen con cadenas de más de un único carácter. for(i=columna; i<max_columna; i++) printf(" "); Finalmente, es muy importante que se controle bien la actualización de la columna en que se pintará la siguiente bola, sobre todo para los márgenes, es decir, para las columnas mínima y máxima. Esto se hace con la siguiente lógica algorítmica: columna = columna + paso; if (columna == -1) {paso = -paso; columna = 1; if (columna == max_columna) paso = -paso; Se aumenta la columna según el paso, que por lo general sólo toma dos valores, 1 ó -1, que indican el sentido que lleva la bola, es decir, va a la derecha o a la izquierda, respectivamente. Durante el movimiento de la bola, ésta podrá llegar a la columna inicial o a la final, de modo que en ambos caso se modifica el sentido de avance, cambiando el signo del paso: paso = -paso;. Sin embargo, los caso son ligeramente diferentes: 1. Columna mínima: Cuando se pinta la bola en la columna mínima, el paso es -1, de modo que al actualizar la columna, ésta valdrá -1, debiendo comprobarse if (columna == -1). Además, debe actualizarse el valor de la columna siguiente en la que debe pintarse la bola, que debe ser la columna 1, pues se acaba de pintar la bola en la columna Columna máxima: Cuando se llega a la columna anterior a la columna máxima y se pinta la bola en ella, el paso vale 1 y se actualiza la columna de forma que su valor es el de la columna máxima. Se comprueba con if (columna == max_columna), y el paso pasa a ser -1. No se requiere modicar el valor de la columna, pues su valor es el de la columna máxima para pintar la bola en la siguiente iteración y cuando se actualice la columna volverá a tomar el valor de la 8

10 columna anterior a la columna máxima. salida: La ejecución del programa principal tal cual (sin uso de señales), proporcionaría la siguiente [enrique@adsl p2]$./alarma o Aunque no puede verse, la bola simulado con la o se movería de un lado a otro rebotando en función de los márgenes definidos. Señales En Linux, los programas responderán a señales o llamadas. Éstas pueden declararse para ser atendidas por la función que deseemos o bien se atenderán de la forma por defecto. En general, cuando no se declara una señal, ésta se tratará por el Sistema Operativo y lo que hará es cerrar el programa. Por ello deben declararse las señales que sean susceptibles de ser recibidas por nuestro programa. Por otro lado, la señal KILL es la única que no podremos definir, ya que de lo contrario podríamos controlarla con una función que no obligara a que nuestro programa fuese matado. Para el control de señales existen dos técnicas diferentes: 1. Declaración con la función signal. Para cada señal que deseemos atender, bastará crear una función que lo haga e indicarlo de la siguiente forma: signal(señal, FUNCIÓN); Por ejemplo, para la señal de alarma (que tiene por valor el número 14, contenido en la macro SIGALRM), que controlaremos con la función muestra_fecha, haremos uso de la siguiente instrucción: signal(sigalrm, muestra_fecha); En el caso de la alarma también será necesario llamar a la función alarm, posteriormente, de 9

11 la forma: alarm(tiempo_alarma); Sin embargo, para la mayoría de señales basta con hacer uso de la función signal, nada más. Como consideración adicional hay que indicar que es recomendable usar las macros de los nombres de las señales en lugar de los números de las mismas, pues pudieran variar sus valores numéricos de unas versiones a otras del kernel de Linux. 2. Estructuras sigaction. En este caso debemos declarar una estructura de tipo sigaction para cada señal que deseemos definir como tratar o atender. struct sigaction senal_alarma, senal_int; Esta forma es más compleja y tediosa que la declaración con la función signal, pero permite mucho más control. A continuación podemos ver los principales campos de esta estructura y las funciones de apoyo de las mismas, comentando la funcionalidad de cada una de ellas. Consultando el man de sigaction podemos ver que la estructura sigaction se define así: struct sigaction { void (*sa_handler)(int); void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void); El campo más importante es el primero, sa_handler, en el que se indica la función que manejará la señal. A continuación se comentan los campos más importantes, incluyendo éste. 1. sa_handler: especifica la acción que se va a asociar con signum y puede ser SIG_DFL para la acción predeterminada, SIG_IGN para no tener en cuenta la señal, o un puntero a una función manejadora para la señal. 2. sa_flags: especifica un conjunto de opciones que modifican el comportamiento del proceso de manejo de señal. Se forma por la aplicación del operador de bits OR a cero o más de las constantes que admite. Por defecto actuará de forma normal, aunque si se desea puede asignársele 0 10

12 o bien hacer uso de la función sigemptyset que se comenta más adelante. 3. sa_mask: da una máscara de señales que deberían bloquearse durante la ejecución del manejador de señal. Además, la señal que lance el manejador será bloqueada, a menos que se activen las opciones SA_NODEFER o SA_NOMASK. Por defecto actuará de forma normal, aunque si se desea puede asignársele 0 o bien hacer uso de la función sigemptyset que se comenta más adelante. La función sigemptyset tiene la forma int sigemptyset(sigset_t *conjunto);. Con ella se inicia el conjunto de señales dado por conjunto al conjunto vacío, con todas las señales fuera del conjunto. Por lo general puede asginarse 0 y se obtiene un resultado similar o bien no hacer nada. Finalmente, y lo más importante para que la atención a la señal tenga efecto, debe hacerse uso de la función sigaction, que tiene la siguiente forma: int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); La llamada al sistema sigaction se emplea para cambiar la acción tomada por un proceso cuando recibe una determinada señal. El parámetro signum especifica la señal y puede ser cualquiera válida salvo SIGKILL o SIGSTOP. Si act no es nulo, la nueva acción para la señal signum se instala como act. Si oldact no es nulo, la acción anterior se guarda en oldact. Por ejemplo, en el caso de la señal de alarma, con sigaction haremos uso de las siguientes sentencias de inicialización o configuración de la estructura: senal_alarma.sa_handler = muestra_fecha; // Acción a Realizar sigaction(sigalrm, &senal_alarma, NULL); Alarma (en Tiempo Real) En Linux puede conseguirse tiempo real, del orden de segundos, con la señal o llamada ALARM. Para ello, usaremos cualquiera de las dos técnicas antes mencionadas para la declaración de la señal y luego declararemos el tiempo de la alarma con: alarm(tiempo_alarma); La variable tiempo_alarma contiene los segundos de duración de la alarma, de modo que el kernel nos enviará dicha señal a nuestro programa pasados exactamente los segundos indicados en 11

13 dicha variable (en tiempo real). Hay que tener en cuenta que esto sólo indica que envíe dicha señal una vez, por lo que una vez se reciba la señal y se haga la tarea desea, habrá que volver a indicar al kernel que nos vuelva a enviar otra señal, volviendo a poner en el código lo mismo: alarm(tiempo_alarma); Esta segunda llamada se hará dentro del proceso de gestión de la alarma, que visto al estilo del signal se indicó de la siguiente forma: signal(sigalrm, muestra_fecha); Con sigaction se haría de la siguiente forma: struct sigaction senal_alarma; senal_alarma.sa_handler = muestra_fecha; sigaction(sigalrm, &senal_alarma, NULL); // Acción a Realizar De este modo, la función muestra_fecha es la que vuelve a pedir la alarma, una vez se ha realizado la tarea deseada en dicha función. Interrupción Adicionalmente a la alarma, como el programa desarrollado es un bucle infinito que hace un uso intensivo de la pantalla, para poder finalizarlo hay que enviarle la señal SIGINT, que no es más que escribir Ctrl+C desde el terminal en que se está ejecutando el programa. Esto provoca la finalización brusca del programa, de modo que hemos optado por controlar dicha señal con la función termina, para que finaliza mostrando un mensaje de finalización: void termina() { printf("el programa ha finalizado correctamente.\n"); exit(0); Con signal declaramos la atención a la señal SIGINT de la siguiente forma: signal(sigint, termina); Mientras que con sigaction lo haremos de la siguiente forma: struct sigaction senal_int; senal_int.sa_handler = termina; // Acción a Realizar sigaction(sigint, &senal_int, NULL); 12

14 Lanzamiento de Procesos Uso de fork El programa que maneja la alarma tiene la tarea de crear un proceso que muestra la fecha, para lo cual hará uso del programa date, existente en el sistema en la ruta /bin/date. Esto se hará con una de las funciones de tipo exec, pero previamente se requiere que se cree un proceso hijo, que ejecute la función muestra_fecha, que es la que se llama cuando se produce la alarma, pues al lanzar el exec, el proceso desaparece y es sustituido por el proceso que ejecuta el date. De este modo, usaremos la llamada al sistema fork, para que se cuando se esté ejecutando la función muestra_fecha por el proceso principal o padre, se cree una copia idéntica de este proceso, pero que será el proceso hijo. El proceso hijo lanzará el exec para que se ejecute el date y muestre la fecha, mientras que el padre seguirá haciendo uso del recurso pantalla, terminando la ejecución de la función muestra_fecha. El código, resumido, que permite esto es el siguiente: int pid; switch (pid = fork()) { case -1: // fork() falla printf("no se pudo crear otro proceso\n"); exit(1); case 0: // Hilo hijo /*... */ default: // Hilo padre /*... */ En el switch se lanza el fork, de modo que a partir de ese momento existen dos procesos, el padre y el hijo, que son idénticos, pero con una ligera diferencia: el valor de la variable pid vale 0 para el hijo y para el padre toma un valor mayor que 0, que es el identificador del proceso (pid) del hijo. Con esta distinción, el hijo ejecutará el código del case 0:, y el padre el del default:. En el caso de que la función fork falle, es decir, no pueda duplicar el proceso, devolverá -1 en la variable pid, y se mostrará un mensaje de error y se abortará la función, según se ve en el case -1:. 13

15 Lo que hace el proceso hijo y el padre, puede verse en la explicación de las llamadas al sistema exec y waitpid, que se muestran a continuación. Uso de exec La función exec permite lanzar un programa, pasándole argumentos si los tubiere. Esta función provoca la desaparición del programa que ejecutaba el proceso que lanza la función exec y todo su espacio de trabajo es ocupado por el del programa llamado por la función exec, es decir, es como si el programa que llama a exec muriese, por lo que debe hacer por el proceso hijo creado con el fork, según se vió en el apartado Uso de fork. El código que ejecutará el proceso hijo (el que está dentro del case 0:) y que hace uso de la llamada al sistema execl (que es una de las muchas variantes del exec) para lanzar el programa date, para que muestre la fecha, es (en este caso no se muestra el control de la sección crítica con pipes, por claridad): execl("/bin/date","fecha",null); Los parámetros de la función execl, de forma genérica son: execl(programa, NOMBRE_PROGRAMA, ARG1, ARG2,..., ARGn, NULL); Esto quiere decir que primero se indica el programa a ejecutar, que en nuestro caso es el date, y pasamos la ruta completa /bin/date. Luego se pone el nombre del programa, que en principio no tiene gran utilidad y luego la lista de parámetros, que deben ser de tipo char * (es decir, ristras), terminando con un NULL; esto hace que los argumentos formen un vector de ristras, que sería de tipo char *argv[], que es el típico parámetro de entrada en las funciones main, para tomar todos los argumentos, y que está precidido por el parámetro int argn, que indica el número de argumentos, incluyendo el nombre del programa. Al ejecutarse el execl muere o desaparece el proceso hijo, por lo que ni siquiera es necesario un break; al final del case 0:; lo mismo ocurre si pusiéramos un exit, pues nunca se ejecutaría, salvo que el execl fallara. El espacio de trabajo pasa a ser ocupado por el programa date. Cuando este programa finaliza su tarea, consistente en el muestreo de la fecha, por pantalla, se encargará de 14

16 indicar la finalización suya y, por tanto, la del proceso hijo que lanzó el execl, quedando indicado el estado de finalización del mismo, útil para la llamada al sistema waitpid, que se ve a continuación. Uso de waitpid El proceso padre se encargará de ver que el proceso hijo finaliza correctamente y en tal caso liberará su espacio de trabajo, sólo cuando el hijo haya terminado su tarea. La llamada al sistema waitpid es la que permite esto. El código que ejecutará el proceso padre, dentro del default:, será (obviando el control de la sección crítica con pipes): waitpid(pid,&estado,wnohang); alarm(tiempo_alarma); Se habrá declarado la variable estado, para recoger el estado del proceso hijo, pero no será necesario testear su valor, pues supondremos que es correcto, si bien es necesario pasarla por referencia como segundo argumento de la función waitpid. El primer parámetro es el identificador del proceso hijo (pid) por el que debe esperarse; también valdría poner -1 para esperar por cualquier proceso hijo, pero como sólo hay uno, no tiene sentido. El último parámetro es indicador del comportamiento del waitpid. Como por defecto, waitpid retendría el proceso padre en ese punto, lo que supondría un control intrínseco de la sección crítica, hacemos que el waitpid no sea bloqueante, con la opción WNOHANG. De esta forma, el proceso padre sigue su ejecución, y cuando el hijo termine, surgirá el efecto del waitpid, lo cual no significa que el contador de programa del proceso padre vuelva poner justo en el waitpid, sino que simplemente se liberará el espacio de trabajo del proceso hijo cuando éste haya terminado. avisarle. Por otro lado, el proceso padre deberá volver a activar la alarma, para que el kernel vuelva a alarm(tiempo_alarma); Uso de exit La llamada al sistema exit es la que permite que un proceso termine, y como parámetro permite que se indica un número entero indicativo del estado de terminación del proceso, para que el padre pueda testear dicho estado de finalización y actuar en consecuencia. Se hace uso del exit, en el case -1:, cuando el fork falla, mostrando un mensaje de erro y 15

17 finalizando el proceso con: exit(1); con el exit: exit(0); También en la función termina, que se llama por la señal SIGINT, se hace la finalizaicón En el primer caso se devuelve 1, indicando error, mientras que en el segundo caso se devuelve 0, que por convenio suele ser el estado correcto de finalización de un proceso. Control de la Sección Crítica, con Pipes Definición de Pipe Un pipe crea un par de descriptores de ficheros, que apuntan a un nodo-í de una tubería, y los pone en el vector de dos elementos apuntado por descf. Así, descf[0] es para lectura, descf[1] es para escritura. Esto se consigue facilmente declarando un vector de elementos y usando la función pipe: int tuberia[2]; pipe(tuberia); Una versión más compleja son las FIFOS, o pipes con nombre, que permiten el uso de las mismas entre programas que no estén relacionados, es decir, que no sean hijos del padre en que se declarán y crean los pipes. Pero como en nuestro caso todos los procesos están relacionados, pues uno es el padre y el otro es el hijo, no habrá problema con el uso de los pipes. El primer paso, para que la tubería funcione bien, es inicializarla introduciendo algo en la misma, para que así el primer proceso que quiera entrar en la sección crítica pueda hacerlo, por lo que prácticamente siempre se hará seguidamente a la creación del pipe, lo siguiente: write(tuberia[1], &valor, sizeof(int)); fflush(null); Esta simplemente provoca la escritura en el pipe. Es necesario el uso de la función fflush para que las escrituras o lecturas del pipe se hagan efectivas. Con NULL se indica que se escriba en todo los ficheros abiertos, vaciando los bufferes de lectura/escritura. Si no se usa el fflush, podrían tener problemas. 16

18 Aunque esto ya es parte del manejo de los pipes, a continuación se comenta claramente como deben manejar, enfocando dicho manejo al control de la sección crítica como problema genérico de programación. Manejo de Pipe Los pipes crean un descritor de fichero de lectura y otro de escritura, de modo que podremos hacer uso de las funciones read y write para leer y escribir en el pipe, respectivamente. Los descriptores será el primer parámetro de estas dos funciones. En nuestro caso tenemos los siguientes descriptores: 1. Descriptor de lectura --> tuberia[0] 2. Descriptor de escritura --> tuberia[1] Para leer del pipe usaremos: read(tuberia[0], &valor, sizeof(int)); fflush(null); Para escribir en el pipe usaremos: write(tuberia[1], &valor, sizeof(int)); fflush(null); El funcionamiento del pipe es muy simple: si no hay nada escrito en el pipe, al leer se bloqueará el programa hasta que se escriba algo. Por otro lado, si se lee algo del pipe, éste se vaciará. No obstante, para que esto funcione así, es necesario que se escriba y lee en igual cantidad, por lo que se escribe y lee simplemente el tamaño de un entero (sizeof(int)), lo cual se indica en el tercer parámetro. Por otro lado, aunque no se use para nada el valor escrito o devuelto, éste debe indicarse, que en nuestro caso se hace con la variable valor, pasado por referencia como segundo parámetro. Adicionalmente, simpre se hace fflush(null); por seguridad. Si leemos del pipe al entrar en la sección crítica, el pipe se vaciará, de modo que si otro proceso va acceder a la sección crítica, cuando lea del pipe quedará bloqueado y no podrá entrar en la sección crítica. Cuando un proceso salga de la sección crítica, escribirá en el pipe, de modo que los procesos bloqueados leyendo del pipe, podrán entrar en la sección crítica. El proceso que entrará 17

19 será el primero que lea del pipe, por lo que pudiera existir inanición si hay muchos procesos esparando por entrar en la sección crítica, pero si solo hay un proceso esperando no existe inanición, como ocurre en nuestro caso. El esqueleto de código sería, por tanto, el siguiente: read(tuberia[0], &valor, sizeof(int)); fflush(null); /* SECCIÓN CRÍTICA */ write(tuberia[1], &valor, sizeof(int)); fflush(null); Este esqueleto sería válido y necesario para todos los procesos que quiesieran entrar en la sección crítica. Problema de la Sección Crítica En nuesto programa, el problema de la sección crítica es debido al uso de la pantalla por ambos procesos. De este modo, lo que se debe hacer es controlar que no escriban los dos procesos a la vez en la pantalla, pues en tal caso lo que escribe uno y otro se entrelazaría. Para evitar este problema se hace uso de pipes para el control de la sección crítica, que es el acceso o uso del recurso pantalla. La solución básica es el uso del esqueleto genérico visto anteriormente, pero en el siguiente apartado se comenta claramente como es la solución en nuestro programa, pues difiere ligeramente. Solución a la Sección Crítica En el programa principal o padre, que hace un uso intensivo de la pantalla, se rodea el uso de la pantalla, que es la sección crítica, por la lectura y escritura en el pipe, teniendo el siguiente código, en el que se muestra sombreado de gris la sección crítica (el uso de la pantalla): read(tuberia[0], &valor, sizeof(int)); fflush(null); printf("\r"); for(i=0; i<columna; i++) printf(" "); printf(bola); for(i=columna; i<max_columna; i++) printf(" "); write(tuberia[1], &valor, sizeof(int)); fflush(null); Por su parte, el proceso hijo es el que debe mostrar la fecha, también por pantalla, de modo que debe usar una solución igual. Sin embargo, hay una diferencia, y es que el hijo lanza el programa date con la llamada al sistema execl, de modo que desaparece o muere. Esto no permite que pueda liberar la sección crítica, es decir, el proceso hijo sólo podrá leer del pipe para bloquear el 18

20 acceso a la sección crítica, antes de lanzar el programa date, pero luego, como muere, no podrá liberar la sección crítica. La solución se consigue haciendo que le proceso padre se encargue de liberar la sección crítica. Así, el proceso padre, justo después del waitpid, liberará la sección crítica, ya que el proceso hijo no puede. Aquí puede verse como el waitpid debe no ser bloqueante, es decir, tener la opción WNOHANG, pues si no, no sería necesario el control de salida de la sección crítica, si bien habría que hacerlo a la entrada, como ahora, para que no imprima la fecha mientras el proceso padre está imprimiendo en pantalla, y luego a la salida, después del waitpid, como ahora, para que el proceso principal no se bloquee al entrar en la sección crítica. Si no se usa WNOHANG, basta poner 0 en su lugar. El código, por tanto, del proceso padre e hijo, que es compartido por ambos, si bien uno ejecuta una parte y el otro otra parte, es e de la función muestra_fecha, y es el siguiente (para el control de la sección crítica, mostrada sombreada de gris): case 0: // Hilo hijo read(tuberia[0], &valor, sizeof(int)); fflush(null); execl("/bin/date","fecha",null); default: // Hilo padre waitpid(pid,&estado,wnohang); write(tuberia[1], &valor, sizeof(int)); fflush(null); Hecho todo esto, el programa producirá la siguiente salida, haciendo uso de los parámetros por defecto, una vez compilado y construido como se indica en el apartado Compilación y Ejecución del programa (Makefile). [enrique@adsl p2]$./alarma o mié mar 23 15:37:05 WET 2005 o mié mar 23 15:37:09 WET 2005 o mié mar 23 15:37:13 WET 2005 o El programa ha finalizado correctamente. 19

21 Compilación y Ejecución del programa (Makefile) El programa desarrollado tiene su código fuente en el fichero alarma.c y se acompaña de un fichero Makefile para se compilación, construcción y ejecución más automática; además de limpiar ficheros creados en tales procesos. A continuación se comenta el fichero Makefile, que define una serie de reglas que podrán lanzarse desde el terminal con el comando make REGLA. Igualmente se comenta como ejecutar el programa desarrollado, así como el paso de parámetros al mismo. Explicación y Reglas del Makefile El fichero Makefile define las siguientes reglas: 1. Compilar Tiene la forma: compilar: limpiar $(COMPILADOR) $(FUENTES) -c $(OPCIONES) Lo primero que hace es llamar a la regla limpiar y luego compila el programa con el COMPILADOR que se indica, para todos los ficheros FUENTES que se indique y además, con las OPCIONES deseadas. Existe una regla alias de ésta que es compile. Su resultado es el siguiente: [enrique@adsl p2]$ make compilar rm -f alarma.o alarma gcc alarma.c -c -Wall -g [enrique@adsl p2]$ ls alarma.c alarma.o Makefile 2. Construir Tiene la forma: construir: compilar $(COMPILADOR) $(NOMBRE).o -o $(NOMBRE) 20

22 Lo primero que hace es llamar a la regla compilar y luego construye el ejecutable, con el COMPILADOR indicado y con el NOMBRE proporcionado. Su resultado es el siguiente: [enrique@adsl p2]$ make construir rm -f alarma.o alarma gcc alarma.c -c -Wall -g gcc alarma.o -o alarma [enrique@adsl p2]$ ls alarma alarma.c alarma.o Makefile Memoria 3. Ejecutar Tiene la forma: ejecutar: construir./$(nombre) $(ARGUMENTOS) Lo primero que hace es llamar a la regla construir y luego ejecuta al programa NOMBRE con los ARGUMENTOS indicados. Por norma general querremos ejecutar el programa, de modo que podemos usar directamente el comando make run, que producirá el siguiente resultado: [enrique@adsl p2]$ make run rm -f alarma.o alarma gcc alarma.c -c -Wall -g gcc alarma.o -o alarma./alarma -b "o" -c 40 -s SIGNAL -t 4 -v o mié mar 23 15:41:07 WET 2005 o mié mar 23 15:41:11 WET 2005 o El programa ha finalizado correctamente. Puede verse como limpia, compila, construye y ejectua el programa alarma pasando una serie de argumentos por defecto. 4. Limpiar Tiene la forma: limpiar: $(RM) $(OBJETOS) $(EJECUTABLES) 21

23 El resultado de limpiar puede verse a continuación: [enrique@adsl p2]$ ls alarma alarma.c alarma.o Makefile [enrique@adsl p2]$ make clean rm -f alarma.o alarma [enrique@adsl p2]$ ls alarma.c Makefile Simplemente borra con el comando RM los ficheros OBJETOS y EJECUTABLES, que habrán creado las otras reglas. Las variables creadas son las siguientes: COMPILADOR = gcc OPCIONES = -Wall -g NOMBRE = alarma FUENTES = $(NOMBRE).c OBJETOS = $(NOMBRE).o EJECUTABLES = $(NOMBRE) TIPO_BOLA = "o" COLUMNA_MAX = 40 TIPO_SIGNAL = SIGNAL TIEMPO_ALARMA = 4 VELOCIDAD = ARGUMENTOS = -b $(TIPO_BOLA) -c $(COLUMNA_MAX) -s $(TIPO_SIGNAL)\ -t $(TIEMPO_ALARMA) -v $(VELOCIDAD) RM = rm -f La variable ARGUMENTOS se compone de los argumentos que puede recibir el programa, que se explican en el siguiente apartado. Ejecución del programa Si simplemente ejecutamos el programa con./alarma se hará uso de los valores por defectos, que hay dentro del código; en el caso del Makefile siempre puede alterarse modificando el propio fichero Makefile. Para tener mayor versatilidad, podemos hacer uso del paso de parámetros, que se explican a continuación, pues de lo contrario, por defecto se tomarán los siguientes valores: Bola = o Columna máxima = 40 22

24 Tipo de señal = SIGNAL Tiempo de alarma = 4 Velocidad = Paso de Parámetros Existen 5 parámetros distintos, a parte de la ayuda con --help. Dichos parámetros tiene una abreviatura para indicarlos y poner seguidamente el valor, de modo que no importa el orden de los mismos. Son los siguientes, si bien ya se comentaron en el apartado Parámetros. -b --> Ristra que emula la bola. -c --> Columna máxima. -s --> Tipo de implementación de las señales (con SIGNAL o con SIGACTION). -t --> Tiempo de la alarma. -v --> Velocidad de la bola; medida de forma inversa, como iteraciones de un bucle. A continuación se muestran algunos ejemplos de ejecución: 1. Modificación de la bola (-b). En el primer caso simplemente emulamos la bola con *, poniendo -b *. [enrique@adsl p2]$./alarma -b "*" * mié mar 23 15:42:21 WET 2005 * mié mar 23 15:42:25 WET 2005 * El programa ha finalizado correctamente. Hay que indicar que el sentido de la variable max_columna (que controla la columna máxima) es el número de columnas que recorre el primer caracter de la ristra que emula la bola, pues así, se mueve lo deseado, si bien el último caracter de la ristra llegara más allá de la columna indicada por max_columna, lo cual se observará viendo el siguiente ejemplo, donde la columna de escritura de la fecha está más a la derecha, en concreto 3 columnas más allá, pues se emula la bola con hola, que tiene 3 caracteres de más que la unidad. [enrique@adsl p2]$./alarma -b hola hola mié mar 23 15:42:41 WET 2005 hola mié mar 23 15:42:45 WET

25 hola mié mar 23 15:42:49 WET 2005 hola mié mar 23 15:42:53 WET 2005 hola El programa ha finalizado correctamente. Finalmente, recordamos que no son necesarias las comillas, pero para ciertos caracteres son necesarias, y para ristras con espacios en blanco también, como se ve a continuación: [enrique@adsl p2]$./alarma -b "Esta es la bola: ()" Esta es la bola: () mié mar 23 15:44:18 WET 2005 Esta es la bola: () mié mar 23 15:44:22 WET 2005 Esta es la bola: () El programa ha finalizado correctamente. Los caracteres que requieren las comillas son aquellos con un significado especial en el terminal, ya que se sustituirán por otras cadenas. Por ejemplo: * --> indica cualquier fichero/carpeta, luego toma el valor del primer fichero/carpeta del directorio por orden alfabético. ~ --> toma el valor del directorio de trabajo del usuario. Etcétera. 2. Modificación de la columna máxima (-c). Se reduce o aumenta el número de columnas por los que se mueve la bola, como se ve en los siguientes ejemplos, en los que se reduce la columna máxima a 5 y 1, respectivamente; hay que recordar que la primera columna del terminal es la 0 y el valor de la columna máxima debe ser mayor que 0, pues de lo contrario fallará la simulación de la bola rebotando. [enrique@adsl p2]$./alarma -c 5 o mié mar 23 15:46:31 WET 2005 o mié mar 23 15:46:35 WET 2005 o mié mar 23 15:46:39 WET 2005 o El programa ha finalizado correctamente. [enrique@adsl p2]$./alarma -c 1 o mié mar 23 15:46:49 WET 2005 o El programa ha finalizado correctamente. 3. Modificación del tipo se señal (-s). A continuación se muestra la ejecución del programa usando señales implementadas con 24

26 SIGNAL y con SIGACTION, respectivamente. Y se observa que el comportamiento no precesente diferencias aparentes. [enrique@adsl p2]$./alarma -s SIGNAL o mié mar 23 15:48:01 WET 2005 o mié mar 23 15:48:05 WET 2005 o El programa ha finalizado correctamente. [enrique@adsl p2]$./alarma -s SIGACTION o mié mar 23 15:48:13 WET 2005 o mié mar 23 15:48:17 WET 2005 o El programa ha finalizado correctamente. 4. Modificación del tiempo de la alarma (-t). Si alteramos la velocidad de la alarma, la frecuencia con la que se muestra la fecha varía. Así, en los siguientes ejemplos puede verse claramente (se ha puesto 1, 4 y 7 segundos respectivamente): [enrique@adsl p2]$./alarma -t 1 o mié mar 23 15:49:09 WET 2005 o mié mar 23 15:49:10 WET 2005 o mié mar 23 15:49:11 WET 2005 o mié mar 23 15:49:12 WET 2005 o mié mar 23 15:49:13 WET 2005 o El programa ha finalizado correctamente. [enrique@adsl p2]$./alarma -t 4 o mié mar 23 15:49:23 WET 2005 o mié mar 23 15:49:27 WET 2005 o El programa ha finalizado correctamente. [enrique@adsl p2]$./alarma -t 7 o mié mar 23 15:49:39 WET 2005 o mié mar 23 15:49:46 WET 2005 o El programa ha finalizado correctamente. 5. Modificación de la velocidad de la bola (-v). La velocidad de la bola no puede apreciarse en las siguientes capturas, pero si pueden comentarse algunas conclusiones, aunque éstas también dependerán de la máquina en que se ejecute el programa. 25

27 p2]$./alarma -v 0 o mié mar 23 15:50:18 WET 2005 o El programa ha finalizado correctamente. [enrique@adsl p2]$./alarma -v o mié mar 23 15:50:39 WET 2005 o El programa ha finalizado correctamente. [enrique@adsl p2]$./alarma -v o mié mar 23 15:50:55 WET 2005 o El programa ha finalizado correctamente. [enrique@adsl p2]$./alarma -v o mié mar 23 15:51:01 WET 2005 o El programa ha finalizado correctamente. Con 0 se tiene la velocidad más rápida y con la más lenta, en la cual se aprecian saltos. Con se ve un movimiento fluido y rápido pero más o menos perceptible. Algunos ejemplos más, de ejecución, haciendo uso de combinaciones de parámetros, se muestran a continuación: 1. Ejemplo 1 Se pone un tiempo de alarma de 1 segundo (-t 1), una velocidad de la bola rápida pero perceptible (-v ) y se emula la bola con el carácter. [enrique@adsl p2]$./alarma -t 1 -v b mié mar 23 15:53:56 WET 2005 mié mar 23 15:53:57 WET 2005 mié mar 23 15:53:58 WET 2005 mié mar 23 15:53:59 WET 2005 mié mar 23 15:54:00 WET 2005 mié mar 23 15:54:01 WET 2005 mié mar 23 15:54:02 WET 2005 El programa ha finalizado correctamente. 2. Ejemplo 2 Se pone un tiempo de alarma de 1 segundo (-t 1), una velocidad de la bola rápida pero perceptible (-v ), se emula la bola con la ristra DSO y se limita la columna máxima a la 3, de modo que el primer carácter que emula la bola (D) sólo podrá llegar a la columna 3 como 26

28 máxima (podrá estar en las columnas 0, 1, 2 y 3); y el último carácter (O) podrá llegar a la columna 5, pues la ristra tiene 2 caracteres más que la unidad (3 + 2 = 5). [enrique@adsl p2]$./alarma -t 1 -v b "DSO" -c 3 DSO mié mar 23 15:56:11 WET 2005 DSO mié mar 23 15:56:12 WET 2005 DSO mié mar 23 15:56:13 WET 2005 DSO mié mar 23 15:56:14 WET 2005 DSO mié mar 23 15:56:16 WET 2005 DSO mié mar 23 15:56:16 WET 2005 DSO mié mar 23 15:56:17 WET 2005 DSOEl programa ha finalizado correctamente. 27

29 Anexo Código Fuente alarma.c #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <string.h> int tuberia[2], tiempo_alarma = 4; void muestra_fecha() { int pid, estado, valor; switch (pid = fork()) { case -1: // fork() falla printf("no se pudo crear otro proceso\n"); exit(1); case 0: // Hilo hijo // Imprime fecha con el programa date (controlando sección crítica con pipe) read(tuberia[0], &valor, sizeof(int)); fflush(null); execl("/bin/date","fecha",null); default: // Hilo padre // Permite liberar el hilo hijo del árbol de procesos waitpid(pid,&estado,wnohang); write(tuberia[1], &valor, sizeof(int)); fflush(null); alarm(tiempo_alarma); void termina() { printf("el programa ha finalizado correctamente.\n"); exit(0); int main(int argn, char *argv[]) { int columna = 0, max_columna = 40, paso = 1, velocidad = , valor, i; int senal_creada = 0; // Indica si se han creado las señales char *bola = "o"; struct sigaction senal_alarma, senal_int; // PASO 1: Parámetros de entrada // Ayuda (--help) if ((argn == 2) && (strcmp(argv[1],"--help") == 0)) { printf("modo de empleo:./alarma [OPCIÓN]\n"); printf("\t-b bola; Ristra que representa la bola\n"); printf("\t-c columna_máxima; Columna máxima a la que llega la bola\n"); printf("\t-s SIGNAL SIGACTION; Implementación de señales (SIGNAL por defecto)\n"); printf("\t-t segundos; Tiempo entre muestreo de la fecha\n"); 28

30 printf("\t-v iteraciones; Velocidad de la bola\n"); exit(0); // Uso Incorrecto if ((argn%2) == 0) { printf("alarma: Forma de uso incorrecta\n"); printf("pruebe:./alarma --help\n"); exit(0); // Toma de Parámetros int p; for(p=1; p<argn; p=p+2) { if (strcmp(argv[p],"-b") == 0) { // Ristra que representa la bola bola = argv[p+1]; else if (strcmp(argv[p],"-c") == 0) { // Columna máxima a la que llega la bola max_columna = atoi(argv[p+1]); else if ((strcmp(argv[p],"-s") == 0) && (!senal_creada)) { // Tipo de implementación de señales senal_creada = 1; if ((strcmp(argv[p+1],"signal") == 0)) { signal(sigalrm, muestra_fecha); signal(sigint, termina); else { senal_alarma.sa_handler = muestra_fecha; // Acción a Realizar sigaction(sigalrm, &senal_alarma, NULL); senal_int.sa_handler = termina; // Acción a Realizar sigaction(sigint, &senal_int, NULL); else if (strcmp(argv[p],"-t") == 0) { // Tiempo entre muestreo de la fecha (alarma) tiempo_alarma = atoi(argv[p+1]); else if (strcmp(argv[p],"-v") == 0) { // Velocidad de la bola velocidad = atoi(argv[p+1]); else{ // Uso Incorrecto printf("alarma: Forma de uso incorrecta\n"); printf("pruebe:./alarma --help\n"); exit(0); // Si no se han creado las señales, se usa SIGNAL por defecto if (!senal_creada) { signal(sigalrm, muestra_fecha); signal(sigint, termina); // PASO 2: Inicializaciones // Creación e inicialización del pipe pipe(tuberia); write(tuberia[1], &valor, sizeof(int)); fflush(null); // Alarma alarm(tiempo_alarma); 29

31 // PASO 3: Bucle de muestreo de la bola while(1) { // PASO 3.1: Pausa entre movimientos de la bola // (sleep(1), solo funciona para segundos enteros) for(i=0; i<velocidad; i++); // PASO 3.2: Mover bola (controlando sección crítica con pipe) read(tuberia[0], &valor, sizeof(int)); fflush(null); printf("\r"); for(i=0; i<columna; i++) printf(" "); printf(bola); for(i=columna; i<max_columna; i++) printf(" "); write(tuberia[1], &valor, sizeof(int)); fflush(null); // PASO 3.3: Actualizar posición de la bola columna = columna + paso; if (columna == -1) {paso = -paso; columna = 1; if (columna == max_columna) paso = -paso; Makefile ############# # Variables # ############# COMPILADOR = gcc OPCIONES = -Wall -g NOMBRE = alarma FUENTES = $(NOMBRE).c OBJETOS = $(NOMBRE).o EJECUTABLES = $(NOMBRE) TIPO_BOLA = "o" COLUMNA_MAX = 40 TIPO_SIGNAL = SIGNAL TIEMPO_ALARMA = 4 VELOCIDAD = ARGUMENTOS = -b $(TIPO_BOLA) -c $(COLUMNA_MAX) -s $(TIPO_SIGNAL)\ -t $(TIEMPO_ALARMA) -v $(VELOCIDAD) RM = rm -f ########## # Reglas # ########## compilar: limpiar $(COMPILADOR) $(FUENTES) -c $(OPCIONES) construir: compilar $(COMPILADOR) $(NOMBRE).o -o $(NOMBRE) 30

32 ejecutar: construir./$(nombre) $(ARGUMENTOS) limpiar: $(RM) $(OBJETOS) $(EJECUTABLES) #################### # Reglas en Inglés # #################### compile: compilar build: construir run: ejecutar clean: limpiar 31

Adaptación al NPGC. Introducción. NPGC.doc. Qué cambios hay en el NPGC? Telf.: 93.410.92.92 Fax.: 93.419.86.49 e-mail:atcliente@websie.

Adaptación al NPGC. Introducción. NPGC.doc. Qué cambios hay en el NPGC? Telf.: 93.410.92.92 Fax.: 93.419.86.49 e-mail:atcliente@websie. Adaptación al NPGC Introducción Nexus 620, ya recoge el Nuevo Plan General Contable, que entrará en vigor el 1 de Enero de 2008. Este documento mostrará que debemos hacer a partir de esa fecha, según nuestra

Más detalles

SOLUCION EXAMEN junio 2006

SOLUCION EXAMEN junio 2006 SOLUCION EXAMEN junio 2006 1. Explique razonadamente si las siguientes afirmaciones son verdaderas o falsas: I) (1 p) En UNIX únicamente se distinguen dos tipos de procesos: los procesos de usuario y los

Más detalles

Objetivos de la práctica: - Practicar uso de ficheros: abrir, cerrar y tratamiento de información contenida en el fichero.

Objetivos de la práctica: - Practicar uso de ficheros: abrir, cerrar y tratamiento de información contenida en el fichero. Objetivos de la práctica: - Practicar uso de ficheros: abrir, cerrar y tratamiento de información contenida en el fichero. Uso de Ficheros Todas las estructuras de datos vistas hasta ahora utilizan la

Más detalles

En cualquier caso, tampoco es demasiado importante el significado de la "B", si es que lo tiene, lo interesante realmente es el algoritmo.

En cualquier caso, tampoco es demasiado importante el significado de la B, si es que lo tiene, lo interesante realmente es el algoritmo. Arboles-B Características Los árboles-b son árboles de búsqueda. La "B" probablemente se debe a que el algoritmo fue desarrollado por "Rudolf Bayer" y "Eduard M. McCreight", que trabajan para la empresa

Más detalles

Programa diseñado y creado por 2014 - Art-Tronic Promotora Audiovisual, S.L.

Programa diseñado y creado por 2014 - Art-Tronic Promotora Audiovisual, S.L. Manual de Usuario Programa diseñado y creado por Contenido 1. Acceso al programa... 3 2. Opciones del programa... 3 3. Inicio... 4 4. Empresa... 4 4.2. Impuestos... 5 4.3. Series de facturación... 5 4.4.

Más detalles

Estructuras de Datos y Algoritmos Tecnólogo en Informática

Estructuras de Datos y Algoritmos Tecnólogo en Informática Estructuras de Datos y Algoritmos Tecnólogo en Informática INSTRUCTIVO DEL COMANDO MAKE ESTRUCTURAS DE DATOS Y ALGORITMOS - TECNÓLOGO EN INFORMÁTICA 1 Contenido Introducción... 3 El archivo makefile...

Más detalles

MANUAL DE AYUDA TAREA PROGRAMADA COPIAS DE SEGURIDAD

MANUAL DE AYUDA TAREA PROGRAMADA COPIAS DE SEGURIDAD MANUAL DE AYUDA TAREA PROGRAMADA COPIAS DE SEGURIDAD Fecha última revisión: Diciembre 2010 Tareas Programadas TAREAS PROGRAMADAS... 3 LAS TAREAS PROGRAMADAS EN GOTELGEST.NET... 4 A) DAR DE ALTA UN USUARIO...

Más detalles

MANUAL COPIAS DE SEGURIDAD

MANUAL COPIAS DE SEGURIDAD MANUAL COPIAS DE SEGURIDAD Índice de contenido Ventajas del nuevo sistema de copia de seguridad...2 Actualización de la configuración...2 Pantalla de configuración...3 Configuración de las rutas...4 Carpeta

Más detalles

COPIAS DE SEGURIDAD AUTOMÁTICAS DE DIRECCIONES CALLEÇPAÑA

COPIAS DE SEGURIDAD AUTOMÁTICAS DE DIRECCIONES CALLEÇPAÑA COPIAS DE SEGURIDAD AUTOMÁTICAS DE DIRECCIONES CALLEÇPAÑA Autor: Carlos Javier Martín González. Licenciado en Física Teórica por la Universidad Autónoma de Madrid. Analista programador y funcional. Desarrollador

Más detalles

Oficina Online. Manual del administrador

Oficina Online. Manual del administrador Oficina Online Manual del administrador 2/31 ÍNDICE El administrador 3 Consola de Administración 3 Administración 6 Usuarios 6 Ordenar listado de usuarios 6 Cambio de clave del Administrador Principal

Más detalles

Ejemplos de conversión de reales a enteros

Ejemplos de conversión de reales a enteros Ejemplos de conversión de reales a enteros Con el siguiente programa se pueden apreciar las diferencias entre las cuatro funciones para convertir de reales a enteros: program convertir_real_a_entero print

Más detalles

Memoria compartida y semáforos r/w. La página del manual que podría servir para describir estas funciones es la siguiente:

Memoria compartida y semáforos r/w. La página del manual que podría servir para describir estas funciones es la siguiente: (3 ptos) Memoria Compartida y Semáforos R/W 1. Objetivo En esta práctica se pretende crear una librería que dé la funcionalidad de un semáforo para resolver problemas con múltiples lectores y escritores

Más detalles

Sistemas Operativos Práctica 3

Sistemas Operativos Práctica 3 Sistemas Operativos Práctica 3 Ing. Andrés Bustamante afbustamanteg@unal.edu.co Ingeniería de Sistemas Facultad de Ingeniería Universidad de la Amazonia 2009 1. Objetivo El objetivo de la práctica es que

Más detalles

INSTRUCTIVO DEL COMANDO MAKE

INSTRUCTIVO DEL COMANDO MAKE INSTRUCTIVO DEL COMANDO MAKE Introducción Un programa escrito en C está normalmente compuesto por varios archivos. Estos archivos se van modificando según se va completando o cambiando el programa. Cada

Más detalles

Una vez que tengamos el padrón de un determinado tributo con todos sus datos actualizados, podemos generar los recibos de ese padrón.

Una vez que tengamos el padrón de un determinado tributo con todos sus datos actualizados, podemos generar los recibos de ese padrón. 11. RECIBOS. Desde esta opción de Menú vamos a completar el proceso de gestión de los diferentes tributos, generando recibos, informes de situación, impresiones, etc. 11.1. GENERACIÓN DE RECIBOS. Una vez

Más detalles

Introducción a la programación orientada a objetos

Introducción a la programación orientada a objetos Introducción a la programación orientada a objetos 1. Introducción a la programación orientada a objetos 2. Las clases 3. El tipo Struct 4. Diferencias entre Class y Struct 5. Pilares de la Programación

Más detalles

port@firmas V.2.3.1 Manual de Portafirmas V.2.3.1

port@firmas V.2.3.1 Manual de Portafirmas V.2.3.1 Manual de Portafirmas V.2.3.1 1 1.- Introducción 2.- Acceso 3.- Interfaz 4.- Bandejas de peticiones 5.- Etiquetas 6.- Búsquedas 7.- Petición de firma 8.- Redactar petición 9.- Firma 10.- Devolución de

Más detalles

Manual Oficina Web de Clubes (FBM)

Manual Oficina Web de Clubes (FBM) Manual Oficina Web de Clubes (FBM) INTRODUCCIÓN: La Oficina Web de Clubes de Intrafeb es la oficina virtual desde la que un club podrá realizar las siguientes operaciones durante la temporada: 1. Ver información

Más detalles

El lenguaje C. #define MAX LINEA 1000 /* maximo tamanio de linea de entrada */

El lenguaje C. #define MAX LINEA 1000 /* maximo tamanio de linea de entrada */ Principios de Programación El lenguaje C 1. Variables locales y globales 1.1. Variables locales Las funciones permiten al programador modularizar un programa. Todas las variables declaradas en las definiciones

Más detalles

MANUAL DE USUARIO DE LA HERAMIENTA CONFIGURACION DE PRESUPUESTOS PARA DISTRIBUIDORES

MANUAL DE USUARIO DE LA HERAMIENTA CONFIGURACION DE PRESUPUESTOS PARA DISTRIBUIDORES MANUAL DE USUARIO DE LA HERAMIENTA CONFIGURACION DE PRESUPUESTOS PARA DISTRIBUIDORES Joma ha creado una herramienta con la cual, usted, como distribuidor, podrá generar presupuestos de las agrupaciones

Más detalles

7. Manejo de Archivos en C.

7. Manejo de Archivos en C. 7. Manejo de Archivos en C. Los datos que hemos tratado hasta el momento han residido en la memoria principal. Sin embargo, las grandes cantidades de datos se almacenan normalmente en un dispositivo de

Más detalles

Creación de Funciones de Conducción

Creación de Funciones de Conducción Creación de Funciones de Conducción Requerimientos Para el desarrollo de esta actividad se requiere que: Contemos con un robot BoeBot armado con placa Arduino. Repetición En estos momentos habremos notado

Más detalles

En términos generales, un foro es un espacio de debate donde pueden expresarse ideas o comentarios sobre uno o varios temas.

En términos generales, un foro es un espacio de debate donde pueden expresarse ideas o comentarios sobre uno o varios temas. 1 de 18 Inicio Qué es un foro En términos generales, un foro es un espacio de debate donde pueden expresarse ideas o comentarios sobre uno o varios temas. En el campus virtual, el foro es una herramienta

Más detalles

La ventana de Microsoft Excel

La ventana de Microsoft Excel Actividad N 1 Conceptos básicos de Planilla de Cálculo La ventana del Microsoft Excel y sus partes. Movimiento del cursor. Tipos de datos. Metodología de trabajo con planillas. La ventana de Microsoft

Más detalles

CAPÍTULO 4. EL EXPLORADOR DE WINDOWS XP

CAPÍTULO 4. EL EXPLORADOR DE WINDOWS XP CAPÍTULO 4. EL EXPLORADOR DE WINDOWS XP Características del Explorador de Windows El Explorador de Windows es una de las aplicaciones más importantes con las que cuenta Windows. Es una herramienta indispensable

Más detalles

MINI MANUAL PARA CREAR FORMULARIOS CON PHP Marzo 2007

MINI MANUAL PARA CREAR FORMULARIOS CON PHP Marzo 2007 MINI MANUAL PARA CREAR FORMULARIOS CON PHP Marzo 2007 Servicio de Informática y Comunicaciones Para poder diseñar un formulario y que éste nos envíe los resultados a nuestro correo electrónico, necesitamos

Más detalles

MANUAL DE AYUDA HERRAMIENTA DE APROVISIONAMIENTO

MANUAL DE AYUDA HERRAMIENTA DE APROVISIONAMIENTO MANUAL DE AYUDA HERRAMIENTA DE APROVISIONAMIENTO Fecha última revisión: Junio 2011 INDICE DE CONTENIDOS HERRAMIENTA DE APROVISIONAMIENTO... 3 1. QUÉ ES LA HERRAMIENTA DE APROVISIONAMIENTO... 3 HERRAMIENTA

Más detalles

GVisualPDA Módulo de Almacén

GVisualPDA Módulo de Almacén GVisualPDA Módulo de Almacén GVisualPDA es una aplicación para Windows Mobile 5/6 que amplía más aún las posibilidades de integración del software de gestión GVisualRec permitiendo estar conectados en

Más detalles

Apuntes de ACCESS. Apuntes de Access. Campos de Búsqueda:

Apuntes de ACCESS. Apuntes de Access. Campos de Búsqueda: Apuntes de ACCESS Campos de Búsqueda: Los campos de búsqueda permiten seleccionar el valor de un campo de una lista desplegable en lugar de tener que escribirlos. El usuario sólo tiene que elegir un valor

Más detalles

UAM MANUAL DE EMPRESA. Universidad Autónoma de Madrid

UAM MANUAL DE EMPRESA. Universidad Autónoma de Madrid MANUAL DE EMPRESA Modo de entrar en ÍCARO Para comenzar a subir una oferta de empleo, el acceso es a través del siguiente enlace: http://icaro.uam.es A continuación, aparecerá la página de inicio de la

Más detalles

Sistemas Operativos I Manual de prácticas

Sistemas Operativos I Manual de prácticas Sistemas Operativos I Manual de prácticas Grupo de Sistemas Operativos (DSIC/DISCA) Práctica 3: Procesos POSIX ANTES DE EMPEZAR...... 2 PRÁCTICA 3: PROCESOS POSIX... 2 CREACIÓN DE PROCESOS MEDIANTE FORK...

Más detalles

Instrucción IrA (GoTo). Saltos no naturales en el flujo normal de un programa. Pseudocódigo y diagramas de flujo. (CU00182A)

Instrucción IrA (GoTo). Saltos no naturales en el flujo normal de un programa. Pseudocódigo y diagramas de flujo. (CU00182A) aprenderaprogramar.com Instrucción IrA (GoTo). Saltos no naturales en el flujo normal de un programa. Pseudocódigo y diagramas de flujo. (CU00182A) Sección: Cursos Categoría: Curso Bases de la programación

Más detalles

MANUAL APLICACIÓN. SOFTWARE GESTIÓN DE CLÍNICAS DENTALES

MANUAL APLICACIÓN. SOFTWARE GESTIÓN DE CLÍNICAS DENTALES 1. ÍNDICE MANUAL APLICACIÓN. SOFTWARE GESTIÓN DE CLÍNICAS DENTALES 1. INTRODUCCIÓN...4 2 INSTALACIÓN DE LA APLICACIÓN...4 3 PANTALLA DE ACCESO...5 4 SELECCIÓN DE CLÍNICA...6 5 PANTALLA PRINCIPAL...7 6.

Más detalles

Mi primer proyecto en Dev-C++

Mi primer proyecto en Dev-C++ Mi primer proyecto en Dev-C++ Para realizar esta actividad deberás disponer de un ordenador en el que esté instalado el Dev-C++. Debes ir realizando cada uno de los pasos indicados, en el mismo orden en

Más detalles

19 4.1.1.0 4 04/05/2009

19 4.1.1.0 4 04/05/2009 Soluciones Informáticas Descripción: Como utilizar la Agenda de Visitas Objetivos: Al finalizar este tutorial el usuario será capaz de utilizar la Agenda de Visitas con sus diferentes opciones: asignar

Más detalles

RESUMEN DE CONCEPTOS BASICOS DE PROGRAMACION JAVA

RESUMEN DE CONCEPTOS BASICOS DE PROGRAMACION JAVA UNED Centro Asociado de Cádiz RESUMEN DE CONCEPTOS BASICOS DE PROGRAMACION JAVA 1. OBJETOS Cualquier elemento del programa es un objeto. Un programa es un conjunto de objetos que se comunican entre sí

Más detalles

GENERACIÓN DE ANTICIPOS DE CRÉDITO

GENERACIÓN DE ANTICIPOS DE CRÉDITO GENERACIÓN DE ANTICIPOS DE CRÉDITO 1 INFORMACIÓN BÁSICA La aplicación de generación de ficheros de anticipos de crédito permite generar fácilmente órdenes para que la Caja anticipe el cobro de créditos

Más detalles

Resumen. Funcionamiento. Advertencia

Resumen. Funcionamiento. Advertencia Resumen Módulo: Librería: IMPEXP.DLL Acoplable a: FactuCont 5, versiones monopuesto y red Descripción: Permite exportar datos de documentos, clientes, proveedores y artículos en un solo fichero para poder

Más detalles

CONCEPTOS BASICOS. Febrero 2003 Página - 1/10

CONCEPTOS BASICOS. Febrero 2003 Página - 1/10 CONCEPTOS BASICOS Febrero 2003 Página - 1/10 EL ESCRITORIO DE WINDOWS Se conoce como escritorio la zona habitual de trabajo con windows, cuando iniciamos windows entramos directamente dentro del escritorio,

Más detalles

Versión 2.01. Página 2 de 29

Versión 2.01. Página 2 de 29 Versión 2.01 Página 2 de 29 Índice Instalación del dispositivo... 4 Protección de CashDro... 4 Configuración de CashDro... 5 Monedas / billetes... 6 Billetes... 6 Monedas... 6 Alertas... 7 Más Opciones...

Más detalles

MANUAL DE AYUDA MODULO TALLAS Y COLORES

MANUAL DE AYUDA MODULO TALLAS Y COLORES MANUAL DE AYUDA MODULO TALLAS Y COLORES Fecha última revisión: Enero 2010 Índice TALLAS Y COLORES... 3 1. Introducción... 3 CONFIGURACIÓN PARÁMETROS TC (Tallas y Colores)... 3 2. Módulos Visibles... 3

Más detalles

Preliminares. Tipos de variables y Expresiones

Preliminares. Tipos de variables y Expresiones Preliminares. Tipos de variables y Expresiones Felipe Osorio Instituto de Estadística Pontificia Universidad Católica de Valparaíso Marzo 5, 2015 1 / 20 Preliminares Computadoras desarrollan tareas a un

Más detalles

GESTINLIB GESTIÓN PARA LIBRERÍAS, PAPELERÍAS Y KIOSCOS DESCRIPCIÓN DEL MÓDULO DE KIOSCOS

GESTINLIB GESTIÓN PARA LIBRERÍAS, PAPELERÍAS Y KIOSCOS DESCRIPCIÓN DEL MÓDULO DE KIOSCOS GESTINLIB GESTIÓN PARA LIBRERÍAS, PAPELERÍAS Y KIOSCOS DESCRIPCIÓN DEL MÓDULO DE KIOSCOS 1.- PLANTILLA DE PUBLICACIONES En este maestro crearemos la publicación base sobre la cual el programa generará

Más detalles

Manual de Procedimiento

Manual de Procedimiento Manual de Procedimiento INSTALACION DEL PROGRAMA Este manual pretende ser una ayuda para el usuario, indicando cada uno de los pasos a seguir en su utilización. REQUERIMIENTOS: 1. Windows 98 o superior.

Más detalles

CATÁLOGO CATÁLOGO CATÁLOGO CATÁLOGO CATÁLOGO

CATÁLOGO CATÁLOGO CATÁLOGO CATÁLOGO CATÁLOGO CATÁLOGO MANUAL DE USUARIO CATÁLOGO MANUAL DE USUARIO CATÁLOGO MANUAL DE USUARIO 1. CATÁLOGO MANUAL DE USUARIO CATÁLOGO AHORA CATÁLOGO MANUAL DE USUARIO 1 1. Introducción AHORA Catálogo es una aplicación

Más detalles

MANUAL PARA EMPRESAS PRÁCTICAS CURRICULARES

MANUAL PARA EMPRESAS PRÁCTICAS CURRICULARES MANUAL PARA EMPRESAS PRÁCTICAS CURRICULARES ÍNDICE 1. Introducción... 3. Registro y Acceso... 3.1. Registro Guiado... 4.1. Registro Guiado Datos Básicos... 5.1. Registro Guiado Contactos... 6 3. Creación

Más detalles

TPV Táctil. Configuración y Uso. Rev. 1.2 21/01/09

TPV Táctil. Configuración y Uso. Rev. 1.2 21/01/09 Configuración y Uso Rev. 1.2 21/01/09 Rev. 2.0 20100616 1.- Ruta de Acceso a Imágenes. 2.- Estructuración de los Artículos. 3.- Creación de Grupos de Familias. 4.- Creación de Familias de Ventas. 5.- Creación

Más detalles

Mantenimiento Limpieza

Mantenimiento Limpieza Mantenimiento Limpieza El programa nos permite decidir qué tipo de limpieza queremos hacer. Si queremos una limpieza diaria, tipo Hotel, en el que se realizan todos los servicios en la habitación cada

Más detalles

5.4. Manual de usuario

5.4. Manual de usuario 5.4. Manual de usuario En esta sección se procederá a explicar cada una de las posibles acciones que puede realizar un usuario, de forma que pueda utilizar todas las funcionalidades del simulador, sin

Más detalles

Ejercicios - Persistencia en Android: ficheros y SQLite

Ejercicios - Persistencia en Android: ficheros y SQLite Ejercicios - Persistencia en Android: ficheros y SQLite Índice 1 Uso de ficheros (0.5 puntos)...2 2 Persistencia con ficheros (0.5 puntos)...3 3 Base de datos: SQLiteOpenHelper (0.5 puntos)... 3 4 Base

Más detalles

Concurrencia. Primitivas IPC con bloqueo

Concurrencia. Primitivas IPC con bloqueo Concurrencia Primitivas IPC con bloqueo Primitivas de IPC con bloqueo La solución de Peterson es correcta, pero tiene el defecto de requerir espera ocupada: Cuando un proceso quiere entrar en su región

Más detalles

Guía para el tratamiento en Allegro de recibos para centros no pertenecientes a la Generalitat Valenciana.

Guía para el tratamiento en Allegro de recibos para centros no pertenecientes a la Generalitat Valenciana. Guía para el tratamiento en Allegro de recibos para centros no pertenecientes a la Generalitat Valenciana. Esta guía muestra como proceder en la configuración y posterior uso de la aplicación Allegro en

Más detalles

MANUAL DE USUARIO DE LA APLICACIÓN DE ACREDITACION DE ACTIVIDADES DE FORMACION CONTINUADA. Perfil Entidad Proveedora

MANUAL DE USUARIO DE LA APLICACIÓN DE ACREDITACION DE ACTIVIDADES DE FORMACION CONTINUADA. Perfil Entidad Proveedora MANUAL DE USUARIO DE LA APLICACIÓN DE ACREDITACION DE ACTIVIDADES DE FORMACION CONTINUADA Perfil Entidad Proveedora El objetivo del módulo de Gestión de Solicitudes vía Internet es facilitar el trabajo

Más detalles

Arranque de la aplicación

Arranque de la aplicación Arranque de la aplicación Acceso autorizado Al ejecutar la aplicación se solicita un nombre de usuario y una clave de acceso. Esto garantiza el acceso a la información de las personas autorizadas. Usuarios

Más detalles

CASO PRÁCTICO DISTRIBUCIÓN DE COSTES

CASO PRÁCTICO DISTRIBUCIÓN DE COSTES CASO PRÁCTICO DISTRIBUCIÓN DE COSTES Nuestra empresa tiene centros de distribución en tres ciudades europeas: Zaragoza, Milán y Burdeos. Hemos solicitado a los responsables de cada uno de los centros que

Más detalles

Operación Microsoft Access 97

Operación Microsoft Access 97 Trabajar con Controles Características de los controles Un control es un objeto gráfico, como por ejemplo un cuadro de texto, un botón de comando o un rectángulo que se coloca en un formulario o informe

Más detalles

Examen Junio- Grupo A Lunes 17 de Junio - Programación en C++ Pág. 1

Examen Junio- Grupo A Lunes 17 de Junio - Programación en C++ Pág. 1 Examen Junio- Grupo A Lunes 17 de Junio - Programación en C++ Pág. 1 ÍNDICE ÍNDICE... 1 1.1 Ejercicio 1: Máquina Expendedora (3.5 ptos.)... 1 1.2 Ejercicio 2: Clase Circulo (1.0 pto.)... 3 1.3 Ejercicio

Más detalles

Person IP CRM Manual MOBILE

Person IP CRM Manual MOBILE Manual MOBILE División Informática BuscPerson Telecomunicaciones : Manual MOBILE 0.- Introducción 3 0.1 Configuración de los terminales 3 0.2 Acceso de Usuarios 3 1.- Funcionalidades CRM 5 1.1 Agenda del

Más detalles

El e-commerce de Grupo JAB es una herramienta que permite a los clientes del Grupo, realizar un amplio conjunto de servicios de consulta, petición y

El e-commerce de Grupo JAB es una herramienta que permite a los clientes del Grupo, realizar un amplio conjunto de servicios de consulta, petición y El de Grupo JAB es una herramienta que permite a los clientes del Grupo, realizar un amplio conjunto de servicios de consulta, petición y compra en los diversos almacenes del Grupo JAB. En concreto podremos:

Más detalles

1.4.1.2. Resumen... 1.4.2. ÁREA DE FACTURACIÓN::INFORMES::Pedidos...27 1.4.2.1. Detalle... 1.4.2.2. Resumen... 1.4.3. ÁREA DE

1.4.1.2. Resumen... 1.4.2. ÁREA DE FACTURACIÓN::INFORMES::Pedidos...27 1.4.2.1. Detalle... 1.4.2.2. Resumen... 1.4.3. ÁREA DE MANUAL DE USUARIO DE ABANQ 1 Índice de contenido 1 ÁREA DE FACTURACIÓN......4 1.1 ÁREA DE FACTURACIÓN::PRINCIPAL...4 1.1.1. ÁREA DE FACTURACIÓN::PRINCIPAL::EMPRESA...4 1.1.1.1. ÁREA DE FACTURACIÓN::PRINCIPAL::EMPRESA::General...4

Más detalles

Capítulo 9. Archivos de sintaxis

Capítulo 9. Archivos de sintaxis Capítulo 9 Archivos de sintaxis El SPSS permite generar y editar archivos de texto con sintaxis SPSS, es decir, archivos de texto con instrucciones de programación en un lenguaje propio del SPSS. Esta

Más detalles

PUESTA EN MARCHA PROGRAMA GESTION DE OPTICAS. Junio - 2004

PUESTA EN MARCHA PROGRAMA GESTION DE OPTICAS. Junio - 2004 PUESTA EN MARCHA PROGRAMA GESTION DE OPTICAS Junio - 2004 pmqsoft Servicios Informáticos, S.L. www.pmqsoft.com soporte@pmqsoft.com Entendiendo que la instalación ha finalizado y que todo ha salido correctamente.

Más detalles

Recuperador datos externos

Recuperador datos externos Recuperador datos externos La opción Recuperar Datos Externos en la opción de Conectividad de la barra de herramientas de Senior, permite realizar importaciones masivas de datos desde ficheros externos..

Más detalles

NOTAS TÉCNICAS SOBRE EL SIT: Comunicados (I)

NOTAS TÉCNICAS SOBRE EL SIT: Comunicados (I) NOTAS TÉCNICAS SOBRE EL SIT: Comunicados (I) Introducción...2 Introducción a los Códigos de Fusión... 2 Modelos de Cartas...2 Elaboración del Modelo... 2 Formato HTML (para envíos por correo electrónico)...

Más detalles

CASO PRÁCTICO. ANÁLISIS DE DATOS EN TABLAS DINÁMICAS

CASO PRÁCTICO. ANÁLISIS DE DATOS EN TABLAS DINÁMICAS CASO PRÁCTICO. ANÁLISIS DE DATOS EN TABLAS DINÁMICAS Nuestra empresa es una pequeña editorial que maneja habitualmente su lista de ventas en una hoja de cálculo y desea poder realizar un análisis de sus

Más detalles

ICARO MANUAL DE LA EMPRESA

ICARO MANUAL DE LA EMPRESA ICARO MANUAL DE LA EMPRESA 1. ENTRANDO EN ICARO Para acceder al Programa ICARO tendremos que entrar en http://icaro.ual.es Figura 1 A continuación os aparecerá la página de Inicio del aplicativo ICARO.

Más detalles

PS.Vending Almacén Pocket PC

PS.Vending Almacén Pocket PC Versión 1.0 Enero 2013 Autor: Pedro Naranjo Rodríguez www.psvending.es Contenido Qué es PS.Vending Almacén Pocket PC?... 3 Funciona PS.Vending Almacén Pocket PC independiente de PS.Vending?... 3 Requisitos...

Más detalles

CÓMO CREAR NUESTRO CATÁLOGO

CÓMO CREAR NUESTRO CATÁLOGO CÓMO CREAR NUESTRO CATÁLOGO Mediante la aplicación (http://www.prensasoft.com/programas/conline) podemos crear nuestros propios catálogos. Para crear un catálogo necesitamos: - Varios productos que mostrar,

Más detalles

Paso de Borland Turbo C (bajo DOS) a Anjuta (Linux) 1.

Paso de Borland Turbo C (bajo DOS) a Anjuta (Linux) 1. Paso de Borland Turbo C (bajo DOS) a Anjuta (Linux) 1. Anjuta es un entorno de desarrollo de C que podemos encontrar en cualquier distribución de GNU/Linux. Si nuestra distribución no dispone de ella,

Más detalles

GUIA APLICACIÓN DE SOLICITUDES POR INTERNET. Gestión de Cursos, Certificados de Aptitud Profesional y Tarjetas de Cualificación de Conductores ÍNDICE

GUIA APLICACIÓN DE SOLICITUDES POR INTERNET. Gestión de Cursos, Certificados de Aptitud Profesional y Tarjetas de Cualificación de Conductores ÍNDICE ÍNDICE ACCESO A LA APLICACIÓN... 2 1.- HOMOLOGACIÓN DE CURSOS... 4 1.1.- INICIAR EXPEDIENTE... 4 1.2.- CONSULTA DE EXPEDIENTES... 13 1.3.- RENUNCIA A LA HOMOLOGACIÓN... 16 2.- MECÁNICA DE CURSOS... 19

Más detalles

GENERACIÓN DE TRANSFERENCIAS

GENERACIÓN DE TRANSFERENCIAS GENERACIÓN DE TRANSFERENCIAS 1 INFORMACIÓN BÁSICA La aplicación de generación de ficheros de transferencias permite generar fácilmente órdenes para que la Caja efectúe transferencias, creando una base

Más detalles

Bibliotecas Escolares. Perfil de Lector.

Bibliotecas Escolares. Perfil de Lector. Bibliotecas Escolares. Perfil de Lector. 2012 Como usuario Lector de AbiesWeb, podrás acceder al catálogo de fondos, solicitar reservas, ver tus préstamos activos, ver el historial de tus lecturas, escribir

Más detalles

GESTIÓN DE EXCEPCIONES EN JAVA. CAPTURA CON BLOQUES TRY CATCH Y FINALLY. EJEMPLOS RESUELTOS. (CU00927C)

GESTIÓN DE EXCEPCIONES EN JAVA. CAPTURA CON BLOQUES TRY CATCH Y FINALLY. EJEMPLOS RESUELTOS. (CU00927C) APRENDERAPROGRAMAR.COM GESTIÓN DE EXCEPCIONES EN JAVA. CAPTURA CON BLOQUES TRY CATCH Y FINALLY. EJEMPLOS RESUELTOS. (CU00927C) Sección: Cursos Categoría: Lenguaje de programación Java nivel avanzado I

Más detalles

15 CORREO WEB CORREO WEB

15 CORREO WEB CORREO WEB CORREO WEB Anteriormente Hemos visto cómo funciona el correo electrónico, y cómo necesitábamos tener un programa cliente (Outlook Express) para gestionar los mensajes de correo electrónico. Sin embargo,

Más detalles

LABORATORIO Nº 2 GUÍA PARA REALIZAR FORMULAS EN EXCEL

LABORATORIO Nº 2 GUÍA PARA REALIZAR FORMULAS EN EXCEL OBJETIVO Mejorar el nivel de comprensión y el manejo de las destrezas del estudiante para utilizar formulas en Microsoft Excel 2010. 1) DEFINICIÓN Una fórmula de Excel es un código especial que introducimos

Más detalles

CONSULTAS CON SQL. 3. Hacer clic sobre el botón Nuevo de la ventana de la base de datos. Aparecerá el siguiente cuadro de diálogo.

CONSULTAS CON SQL. 3. Hacer clic sobre el botón Nuevo de la ventana de la base de datos. Aparecerá el siguiente cuadro de diálogo. CONSULTAS CON SQL 1. Qué es SQL? Debido a la diversidad de lenguajes y de bases de datos existentes, la manera de comunicar entre unos y otras sería realmente complicada a gestionar de no ser por la existencia

Más detalles

Introducción al tipo de dato ARRAY

Introducción al tipo de dato ARRAY CONTENIDOS. Introducción al tipo de dato ARRAY. Definición, Características, Declaración, Acceso e Inicialización.. Arrays multidimensionales Definición, Declaración, Acceso e Inicialización. Introducción

Más detalles

Access Control. Manual de Usuario

Access Control. Manual de Usuario Access Control Manual de Usuario Contenido Login... 3 Pantalla Principal... 3 Registro de Acceso... 4 Catálogos... 5 Empleados... 5 Departamentos... 8 Puestos... 9 Perfiles... 9 Usuarios... 11 Horarios...

Más detalles

Sistemas Inteligentes de Gestión. Relación de ejercicios CLIPS. Sistemas expertos basados en reglas con encadenamiento hacia adelante

Sistemas Inteligentes de Gestión. Relación de ejercicios CLIPS. Sistemas expertos basados en reglas con encadenamiento hacia adelante Sistemas Inteligentes de Gestión Relación de ejercicios CLIPS Sistemas expertos basados en reglas con encadenamiento hacia adelante Juan Carlos Cubero & Fernando Berzal ENTREGA DE LA PRÁCTICA clips.doc

Más detalles

Abelardo Pardo. Iria Estévez Ayres. Damaris Fuentes Lorenzo. Pablo Basanta Val. Pedro J. Muñoz Merino. Hugo A. Parada.

Abelardo Pardo. Iria Estévez Ayres. Damaris Fuentes Lorenzo. Pablo Basanta Val. Pedro J. Muñoz Merino. Hugo A. Parada. Arquitectura de sistemas Abelardo Pardo University of Sydney School of Electrical and Information Engineering NSW, 2006, Australia Autor principal del curso de 2009 a 2012 Iria Estévez Ayres Damaris Fuentes

Más detalles

Manual Oficina Web de Clubes - Federaciones Autono micas y Delegaciones

Manual Oficina Web de Clubes - Federaciones Autono micas y Delegaciones Manual Oficina Web de Clubes - Federaciones Autono micas y Delegaciones Este manual muestra el funcionamiento de una Federación Autonómica o Delegación en el uso de Intrafeb, todos los pasos que a continuación

Más detalles

Gestión de Retales WhitePaper Noviembre de 2009

Gestión de Retales WhitePaper Noviembre de 2009 Gestión de Retales WhitePaper Noviembre de 2009 Contenidos 1. Introducción 3 2. Almacén de retales 4 3. Propiedades de los materiales 6 4. Alta de retales 8 5. Utilización de retales en un lote de producción

Más detalles

MANUAL DE LA CONFIGURACIÓN Y USO DEL MÓDULO DE ASM PARA PRESTASHOP

MANUAL DE LA CONFIGURACIÓN Y USO DEL MÓDULO DE ASM PARA PRESTASHOP MANUAL DE LA CONFIGURACIÓN Y USO DEL MÓDULO DE ASM PARA PRESTASHOP Contacto Para las dudas con la instalación: Integración de Clientes (iclientes.inf@asmred.es) Para el contacto comercial: 91 327 28 80

Más detalles

Cierre y Apertura de ejercicio. Gestión - Contabilidad

Cierre y Apertura de ejercicio. Gestión - Contabilidad Cierre y Apertura de ejercicio. Gestión - Contabilidad Cliente : Cooperativa Madrileña de Ferreteros, soc. coop. Referencia : I-3-PC-02 / 000041 Asunto : Cierre y apertura de ejercicio. Gestión Contabilidad

Más detalles

28.- Manejo de los Feriados

28.- Manejo de los Feriados 28.- Manejo de los Feriados El feriado anual o vacaciones pagadas es el derecho del trabajador con más de un año de servicios a hacer uso de un descanso anual de 15 días hábiles, con remuneración íntegra,

Más detalles

Tutorial de Introducción a la Informática Tema 0 Windows. Windows. 1. Objetivos

Tutorial de Introducción a la Informática Tema 0 Windows. Windows. 1. Objetivos 1. Objetivos Este tema de introducción es el primero que debe seguir un alumno para asegurar que conoce los principios básicos de informática, como el manejo elemental del ratón y el teclado para gestionar

Más detalles

Capítulo 0. Introducción.

Capítulo 0. Introducción. Capítulo 0. Introducción. Bueno, por fin está aquí el esperado (espero!!) Capítulo Cero del Tutorial de Assembler. En él estableceremos algunos conceptos que nos serán de utilidad a lo largo del Tutorial.

Más detalles

2.1.- EJEMPLO DE UN PROGRAMA FORTRAN

2.1.- EJEMPLO DE UN PROGRAMA FORTRAN 2.1.- EJEMPLO DE UN PROGRAMA FORTRAN Con el presente apartado comenzaremos a conocer cómo se escribe un programa en lenguaje FORTRAN bajo el entorno de programación FORTRAN. En primer lugar conozcamos

Más detalles

G R U P O S INDICE Cómo crear una cuenta en ARQA? Cómo tener un grupo en ARQA? Secciones y funcionalidades de los grupos Configuración del grupo

G R U P O S INDICE Cómo crear una cuenta en ARQA? Cómo tener un grupo en ARQA? Secciones y funcionalidades de los grupos Configuración del grupo INDICE Cómo crear una cuenta en ARQA? 4 Cómo tener un grupo en ARQA? 5 Secciones y funcionalidades de los grupos 6 Muro del Grupo 6 Compartir Textos 8 Compartir Imágenes 9 Compartir videos 10 Compartir

Más detalles

Guía nuevo panel de clientes Hostalia

Guía nuevo panel de clientes Hostalia Guía nuevo panel de clientes Hostalia Cardenal Gardoki, 1 48008 BILBAO (Vizcaya) Teléfono: 902 012 199 www.hostalia.com 1. Estructura del panel de administración El panel de control presenta un diseño

Más detalles

PROGRAMA PARA LA RECEPCIÓN VALIDACIÓN Y RESGUARDO DE DOCUMENTOS FISCALES VERSIÓN 1.00 MANUAL DE OPERACIÓN

PROGRAMA PARA LA RECEPCIÓN VALIDACIÓN Y RESGUARDO DE DOCUMENTOS FISCALES VERSIÓN 1.00 MANUAL DE OPERACIÓN PROGRAMA PARA LA RECEPCIÓN VALIDACIÓN Y RESGUARDO DE DOCUMENTOS FISCALES VERSIÓN 1.00 MANUAL DE OPERACIÓN ENERO 2014 Versión 1.00 Página 1 de 12 CONTENIDO 1.- Introducción 2.- Entrar y Salir del Programa

Más detalles

Sitios remotos. Configurar un Sitio Remoto

Sitios remotos. Configurar un Sitio Remoto Sitios remotos Definir un sitio remoto significa establecer una configuración de modo que Dreamweaver sea capaz de comunicarse directamente con un servidor en Internet (por eso se llama remoto) y así poder

Más detalles

... Formas alternativas de escribir un texto. Columnas. anfora CAPÍTULO 4

... Formas alternativas de escribir un texto. Columnas. anfora CAPÍTULO 4 CAPÍTULO 4. Formas alternativas de escribir un texto........ Columnas Para fijar columnas se posiciona el Punto de Inserción donde se desee que comiencen las columnas, o bien se selecciona el texto que

Más detalles

Gestión del Stock 1. Creación de referencias 2. Dar de alta a mercancía y proveedores 3. Añadir o eliminar artículos de albarán 4. Etiquetado 5. Consulta de existencias de stock, tipo de proveedor, precio

Más detalles

Anexo B. Comunicaciones entre mc y PC

Anexo B. Comunicaciones entre mc y PC Anexo B Comunicaciones entre mc y PC En este apartado se hará hincapié en los comandos para el manejo del módulo de comunicaciones desde el PC. Conociendo estos comando se podrá realizar una aplicación

Más detalles

Prof. Dr. Paul Bustamante

Prof. Dr. Paul Bustamante Prácticas de C++ Practica Nº 10 Informática II Fundamentos de Programación Prof. Dr. Paul Bustamante INDICE 1.1 EJERCICIO 1: MI PRIMER FICHERO EN BINARIO... 1 1.2 EJERCICIO 2: LEYENDO MI PRIMER FICHERO

Más detalles

Puesta en Marcha versión Monousuario

Puesta en Marcha versión Monousuario Puesta en Marcha versión Monousuario Criterium www.criterium.es Antonio Muñoz Sánchez criteriumcyp@criterium.es 950 442 281 Puesta en Marcha versión Monousuario 1 Limitaciones de versión monopuesto...3

Más detalles

Presentaciones. Con el estudio de esta Unidad pretendemos alcanzar los siguientes objetivos:

Presentaciones. Con el estudio de esta Unidad pretendemos alcanzar los siguientes objetivos: UNIDAD 8 Presentaciones Reunión. (ITE. Banco de imágenes) as presentaciones son documentos formados por una sucesión de páginas, llamadas diapositivas, que transmiten información estructurada de manera

Más detalles

Ejercicio 1. Desarrollar un pequeño juego para practicar mecanografía.

Ejercicio 1. Desarrollar un pequeño juego para practicar mecanografía. Examen Curso 2001-2002. Convocatoria de Febrero Página 1 Ejercicio 1. Desarrollar un pequeño juego para practicar mecanografía. Este ejercicio se divide en dos partes con el fin de que el alumno no intente

Más detalles

CURSOS PRÁCTICOS SEDEN. Maquetación de un trabajo en Word SEDEN

CURSOS PRÁCTICOS SEDEN. Maquetación de un trabajo en Word SEDEN 2 CURSOS PRÁCTICOS SEDEN Maquetación de un trabajo en Word SEDEN 2 Maquetación de un trabajo en Word Vamos a explicar las distintas herramientas que tiene Word para maquetar cualquier trabajo que realicemos.

Más detalles