Sunteți pe pagina 1din 12

MDULO DE SINCRONIZACIN Y COMUNICACIN

El mdulo de sincronizacin y comunicacin se estructura en los siguientes apartados: Introduccin Concurrencia, comparticin y coordinacin Condicin de carrera Coordinacin implcita vs. Coordinacin explcita Modelo Productor Consumidor Modelo Lectores Escritores Modelo Cliente Servidor

INTRODUCCIN
Este mdulo incide fundamentalmente en los servicios POSIX para la sincronizacin y la comunicacin, tanto de procesos ligeros como pesados. Unas veces sern servicios del sistema operativo y otros sern servicios proporcionados a nivel de biblioteca (por ejemplo por la biblioteca pthread). Se utilizarn los siguientes programas, que debern descargarse de la web y compilar para su ejecucin:
Carreras.c Concurr_prc.c Lector.c Compart_pth.c CPUs_prc.c TCP_c.c Compart_prc.c CPUs_pth.c TCP_s.c Concurr_pth.c Escritor.c Times_C.c

UnSegundo.c Ventanilla_pth.c Ventanilla_prc.c Ventanilla_srl.c

Los servicios y funciones de biblioteca utilizados en dichos programas son los siguientes:
accept bzero execvp fork getpid lseek open pthread_cancel pthread_cond_wait pthread_mutex_init pthread_setcanceltype send socket toupper alarm calloc exit fprintf htons memcpy perror pthread_cond_destroy pthread_create read shutdown strlen usleep write atoi close fcntl getenv kill mmap poll pthread_cond_init pthread_join recv signal sysconf wait bind connect fflush gethostbyname listen munmap printf pthread_cond_signal pthread_mutex_destroy sched_yield sizeof times waitpid

pthread_mutex_lock pthread_mutex_unlock pthread_setcancelstate

CONCURRENCIA
En un sistema UNIX la concurrencia sucede a muchos niveles. Actualmente, en la mayora de los sistemas operativos modernos encontramos las siguientes caractersticas relacionadas con su capacidad de concurrencia: Sistema multiproceso: el sistema permite lanzar mltiples mandatos o aplicaciones, que, al ejecutar, sern mltiples procesos. Todos los procesos del sistema ejecutarn concurrentemente. El sistema crea la ficcin de una CPU (virtual) exclusiva para ejecutar cada proceso. Un sistema puede ser multiproceso incluso cuando slo dispone de una nica CPU. En este ltimo caso, de acuerdo a la planificacin del SO, los procesos intercalan su ejecucin en la nica CPU existente. Sistema multiusuario: mltiples usuarios pueden conectarse y trabajar concurrentemente sobre el sistema. Sistema multiprocesador: el sistema explota todos los recursos de cmputo disponibles. Si la mquina dispone de varias CPUs, ninguna quedar ociosa mientras existan procesos listos para ejecutar. Podr haber en ejecucin paralela real tantos hilos de ejecucin como procesadores tenga la mquina. Ciertas tecnologas modernas ofrecen incluso ms: HyperThreading permite dos hilos de ejecucin por procesador. DualCore encapsula dos procesadores completos en un nico Chip. QuadCore encapsula cuatro procesadores completos en un nico Chip. Captura de seales: un proceso puede decidir ejecutar una funcin cuando el sistema notifique un evento dado, va una determinada seal. La ejecucin de la funcin asociada ser asncrona (y en cierto sentido concurrente) respecto de la del hilo principal del proceso. Proceso multihilo: un hilo del proceso puede crear otro. Todos los hilos del proceso comparten un nico espacio de memoria. Se usan tcnicas de programacin concurrente, utilizando servicios ofrecidos por una biblioteca o por el sistema operativo. Biblioteca multihilo: conjunto de servicios para programacin multihilo, sin que el sistema operativo se entere. La biblioteca multiplexa el nico hilo que el sistema operativo ofrece por proceso. Si se bloquea un hilo se est bloqueando el nico hilo del proceso. Sistema multihilo: el sistema ofrece el conjunto de servicios para la programacin multihilo. El sistema operativo gestiona que un proceso tenga ms de un hilo. Todos

los hilos del proceso comparten un nico espacio de memoria. Si un hilo se bloquea, los dems hilos del proceso no se ven afectados. Un proceso multihilo, sobre un sistema multihilo, sobre un multiprocesador, podra estar ejecutando simultneamente en paralelo en ms de una CPU, esto es, obteniendo tasas de utilizacin de CPU de ms del 100%. Este mismo proceso multihilo (usando una biblioteca multihilo), sobre un sistema monohilo, ejecutara como mximo al 100% de CPU, aunque el sistema sea multiprocesador. Para que la realizacin de esta primera tanda de preguntas ofrezca resultados interesantes, se recomienda encarecidamente que las realice en la mquina triqui.fi.upm.es. Se pide que se introduzca usted en un sistema UNIX donde tenga cuenta abierta. Un sistema UNIX es multiproceso y multiusuario.

Analicemos ahora el tipo de sistema con el que est trabajando. El directorio /proc, como ya habamos visto anteriormente, recoge informacin sobre el sistema. Entre esta informacin se encuentra las caractersticas del procesador, en concreto, en el ficherocpuinfo. processor.- nos indica el nmero de procesadores virtuales que contiene la mquina. physical id.- nos proporciona el identificador fsico de cada uno de los procesadores que contiene la mquina. Como es de esperar, si varios procesadores tienen el mismo physical id, es porque se trata del mismo procesador fsico. cpu cores.- nos permite conocer el nmero de ncleos que existen por procesador fsico. Un valor de '1' indicar, por tanto, que el procesador contiene un nico ncleo. Si el numero de procesadores virtuales es mayor que el nmero de procesadores fsicos mltiplicado por el nmero de ncleos que tiene cada procesador, entonces la mquina utiliza hyper-threading . La tecnologa de hyperthreading estar soportada si el flag ht est presente en el campo flags y si se utiliza kernel SMP. Dada la informacin contenida en /proc/cpuinfo , conteste a las siguientes preguntas:

Adems de la informacin proporcionada por /proc/cpuinfo, proporcionamos dos programas CPUs_pth y CPUs_prc, que nos van a permitir conocer (en cierto modo) la capacidad de computo del sistema (entendida como nmero total de incrementos de una variable de 64 bits) que pueden conseguir el nmero de procesos (o hilos) indicado en el nmero de segundos establecidos. Como se puede imaginar, este no es un mtodo fiable,

puesto que depende de la carga (de procesos) a la que est sometida la mquina. Si en el sistema hay otros procesos que usan intensivamente la CPU es fcil que las medidas que usted obtenga sean muy dispares. Analice el cdigo del programa CPUs_prc. Comprobar que se crean tantos procesos (mediante fork) como se indique en el primer argumento, y que cada uno de estos procesos estar en ejecucin durante un tiempo determinado por el segundo argumento. Compile y ejecute el programa, por ejemplo, con los argumentos 1 10:
alumno@maquinaLinux~/PracticasAnalisis/ModuloSinCom$ ./CPUs_prc 1 10 Total work done by 1 process in 10 seconds is = 498176612

Adems podemos utilizar el programa Times_C.c que nos va a permitir conocer el tiempo real que un proceso ha estado en ejecucin, y adems el tiempo de procesador (usuario) que ha utilizado el proceso. Como es lgico pensar, si nuestro proceso es multihilo (como es el caso en CPUs_prc.c ), y nuestro sistema es multiprocesador, podr suceder que cada uno de los hilos de ejecucin se asignen a procesadores diferentes por lo que el tiempo de procesador (usuario) ser superior al tiempo real.
alumno@maquinaLinux~/PracticasAnalisis/ModuloSinCom$ ./Times_C ./CPUs_prc 1 10 Total work done by 1 process in 10 seconds is = 4982684141 Times_C: Real:10.000" User:10.000" Syst:0.000"

El resultado muestra como durante 10 segundos, 1 proceso en ejecucin ha logrado realizar un total aproximado de 5000 millonesde sumas. Cunto cmputo pueden realizar el doble de procesos en la mitad de tiempo? El mismo o la mitad? Esto depende de si tenemos una nica CPU o tenemos ms (y obviamente de la carga del sistema).
alumno@maquinaLinux~/PracticasAnalisis/ModuloSinCom$ ./Times_C ./CPUs_prc 2 5 Total work done by 2 process in 5 seconds is = 4979025368 Times_C: Real:5.010" User:10.000" Syst:0.000"

Resulta que efectivamente se alcanza una cantidad de cmputo prcticamente idntica (del orden de los 5000 millones). De ello podramos deducir que nuestra mquina es, al menos, un biprocesador. Adems vemos como el tiempo de procesador (en modo usuario) es el doble que el tiempo real, lo cual implica que cada proceso ha estado ejecutando en un procesador diferente. Recuerde que estamos haciendo todo este tipo de pruebas sobre un sistema multiproceso y multiusuario, luego las medidas de tiempos que podamos hacer sern siempre aproximadas y prcticamente irrepetibles, al estar sometidas al indeterminismo del resto de la carga en el sistema. El programa CPUs_pth.c presenta la misma funcionalidad que el programa CPUs_prc.c, pero utilizando procesos ligeros o threads. Siguiendo el mismo procedimiento que para CPUs_prc.c, podemos determinar si nuestro sistema es multihilo o si por el contrario el soporte para los threads es mediante una biblioteca multihilo.

Ciertos programas que ya se utilizaron en el captulo de procesos nos permiten observar cmo sucede la concurrencia en o entre los procesos existentes en un sistema. Nos estamos refiriendo a: Compart_*, Concurr_*, UnSegundo.c y Ventanilla_*.

CONDICIN DE CARRERA
El acceso concurrente sin coordinacin a recursos compartidos puede NO producir los resultados esperados. En sistemas multiproceso, no es posible garantizar la velocidad relativa de los diferentes procesos en ejecucin, es decir, no vamos a conocer a priori el orden en que se ejecutarn los procesos en nuestro sistema. Este hecho provoca que un acceso no coordinado a los recursos conpartidos por los procesos pueda producir resultados diferentes a los esperados. Este fenmeno se conoce como condicin de carrera. Se ha desarrollado el programa Carreras.c que pretende demostrar la existencia de condiciones de carrera, cuando no existe coordinacin en el acceso a un recurso compartido por varios procesos. Analice el cdigo del programa Carreras.c
C-01.C-02.C-03.C-04.C-05.C-06.C-07.C-08.C-09.C-10.C-11.C-12.C-13.C-14.C-15.C-16.C-17.C-18.C-19.C-20.C-21.C-22.C-23.C-24.C-25.C-26.C-27.C-28.C-29.C-30.C-31.C-32.C-33.C-34.void shared_free(void * ptr, unsigned size) { munmap(ptr, size); } void * shared_alloc(unsigned size) { void * ptr = NULL; int fd = open("/dev/zero", O_RDWR); if (fd < 0) return NULL; ptr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); close(fd); return ptr; } #define X(a) { (a); (a); (a); (a); (a); }

int main(void) { int i, v; volatile int * Variable = shared_alloc(sizeof(int)); for (i = 0; i < 50; i++) { Variable[0] = 0; switch(fork()) { case -1: perror(MYNAME": fork()"); exit(1); case 0: for (v=0;v<10000;v++) X(X(Variable[0]++)); exit(0); default: for (v=0;v<10000;v++) X(X(Variable[0]--)); wait(NULL); }

C-35.C-36.C-37.C-38.C-49.C-40.- }

printf ("\t%10d\n ", Variable[0]); } shared_free((void*)Variable, sizeof(int)); return 0;

COORDINACIN IMPLICITA VS. COORDINACIN EXPLICITA


Para evitar las condiciones de carrera, es necesario coordinar los accesos al recurso compartido. Coordinacin implcita: es aquella que realiza motu proprio el Sistema Operativo para garantizar que no suceden condiciones de carrera entre procesos que, aparentemente, son independientes, pero que en realidad estn compartiendo recursos del sistema. Por poner un ejemplo, este es el caso de la posicin sobre el archivo, que comparten los procesos a travs de descriptores de fichero duplicados. Entre las diferentes pruebas que se realizaron en el guin del tema de Sistema de Ficheros, hubo una que mostraba como el comportamiento es diferente cuando padre e hijo comparten la posicin sobre el fichero y cuando no. Se trata del programa PunteroFichero que al ser invocado con una C como segundo argumento, debe crear el archivo indicado como primer argumento, y padre e hijo, compartiendo la posicin sobre el archivo, escriben 310 caracteres cada uno. El resultado ser un archivo de 620 bytes, como se muestra en el ejemplo siguiente.
alumno@maquinaLinux~/PracticasAnalisis/ModuloFicheros$ ./PunteroFichero compartiendo C alumno@maquinaLinux~/PracticasAnalisis/ModuloFicheros$ ls l compartiendo -rw------- 1 alumno grupoAlumno 620 2009-09-09 20:25 compartiendo

Si se analiza el cdigo de dicho programa, se comprobar que en ningn momento se utiliza de manera explicita ningn mecanismo que permita el acceso de manera coordinada al recurso compartido. Sin embargo, el sistema operativo se encarga de garantizar que mientras un proceso est accediendo al fichero, ninguno ms pueda modificarlo. Coordinacin explcita: es aquella que realiza explcitamente el programador, utilizando los mecanismos de sincronizacin adecuados, proporcionados por el lenguaje o por el Sistema Operativo, para conseguir que no sucedan condiciones de carrera entre procesos concurrentes que est programando y que estn compartiendo recursos. En clase se ven ejemplos de la utilizacin de diversos mecanismos de sincronizacin para la implementacin de determinados modelos clsicos de programacin concurrente.

MODELO PRODUCTOR CONSUMIDOR


Este modelo de interaccin entre dos procesos concurrentes resuelve el problema de cmo comunicar (ordenadamente) informacin de uno a otro (en un sentido), cuando lo nico que los dos procesos tienen en comn es un espacio de almacenamiento de tamao fijo limitado. Utilizaremos en este apartado, el programa PC_PLs_mc.c, el cual constituye un ejemplo del modelo productor|consumidor utilizando procesos ligeros.
PC-01.PC-02.PC-03.PC-04.PC-05.PC-06.PC-07.PC-08.PC-09.PC-10.PC-11.PC-12.PC-13.PC-14.PC-15.PC-16.PC-17.PC-18.PC-19.PC-20.PC-21.PC-22.PC-23.PC-24.PC-25.PC-26.PC-27.PC-28.PC-29.PC-30.PC-31.PC-32.PC-33.PC-34.PC-35.PC-36.PC-37.PC-38.PC-39.PC-40.PC-41.PC-42.PC-43.PC-44.PC-45.PC-46.PC-47.PC-48.PC-49.PC-50.#define BUFF_SIZE #define TOTAL_DATOS 1024 100000

int n_datos; int buffer[BUFF_SIZE]; pthread_mutex_t mutex; pthread_cond_t no_lleno, no_vacio; void Productor(void) { int i, dato; for (i = 0; i < TOTAL_DATOS; i++) { /*Producir el dato*/ dato = i; pthread_mutex_lock(&mutex); while (n_datos == BUFF_SIZE) pthread_cond_wait(&no_lleno, &mutex); buffer[i % BUFF_SIZE] = dato; n_datos++; printf ("PRODUCTOR: %d \n", dato); pthread_cond_signal(&no_vacio); pthread_mutex_unlock(&mutex); } } void Consumidor(void) { int i, dato; for (i = 0; i < TOTAL_DATOS; i++) { pthread_mutex_lock(&mutex); while (n_datos == 0) pthread_cond_wait(&no_vacio, &mutex); dato = buffer[i % BUFF_SIZE]; n_datos--; pthread_cond_signal(&no_lleno); pthread_mutex_unlock(&mutex); /*Consumir el dato*/ printf ("CONSUMIDOR: %d fflush(stdout); } printf ("\n"); fflush(stdout); } int main(void)

\n", dato);

PC-51.- { PC-52.pthread_t th1, th2; PC-53.PC-54.pthread_mutex_init(&mutex, NULL); inicial */ PC-55.pthread_cond_init(&no_lleno, NULL); PC-56.pthread_cond_init(&no_vacio, NULL); PC-57.pthread_create(&th1, NULL, (void*)Productor, NULL); */ PC-58.pthread_create(&th2, NULL, (void*)Consumidor, NULL); PC-59.pthread_join(th1, NULL); terminacin */ PC-60.pthread_join(th2, NULL); PC-61.pthread_mutex_destroy(&mutex); */ PC-62.pthread_cond_destroy(&no_lleno); PC-63.pthread_cond_destroy(&no_vacio); PC-64.PC-65.return 0; PC-66.- }

/* Situacin

/* Arranque

/* Esperar

/* Destruir

Compile (tenga en cuenta que utiliza procesos ligeros) y ejecute el programa:

MODELO LECTORES ESCRITORES


Este modelo de interaccin entre procesos concurrentes resuelve el problema de ordenar los accesos a un repositorio comn de informacin, de manera que se garantice una visin coherente de dicha informacin. Se debe permitir que varios lectores puedan acceder simultneamente al recurso, pero al mismo tiempo se debe garantizar que cada escritor acceda en exclusiva, es decir, mientras un proceso escritor accede al recurso ningn otro proceso (ya sea lector o escritor) deber acceder al mismo. Para mostrar el funcionamiento de este modelo, se plantea la utilizacin de dos programas: Lector.c y Escritor.c. El primer realiza lecturas sobre un fichero compartido, que se ha definido de manera esttica como BD, mientras que el proceso escritor, realiza lecturas sobre dicho fichero compartido. A continuacin se muestra el cdigo del programa Escritor.c
E-01.E-02.E-03.E-04.E-05.E-06.E-07.E-08.E-09.E-10.E-11.E-12.#define MYNAME "Escritor" #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(void) { int fd, val=0, cnt; struct flock fl; fl.l_whence = SEEK_SET;

E-13.E-14.E-15.E-16.E-17.E-18.E-19.E-20.E-21.E-22.E-23.E-24.E-25.E-26.E-27.E-28.E-29.E-30.- }

fl.l_start = 0; fl.l_len = 0; fl.l_pid = getpid(); fd = open("BD", O_RDWR); for (cnt = 0; cnt < 10; cnt++) { fl.l_type = F_WRLCK; fcntl(fd, F_SETLKW, &fl); lseek(fd, 0, SEEK_SET); read(fd, &val, sizeof(int)); val++; lseek(fd, 0, SEEK_SET); write(fd, &val, sizeof(int)); fl.l_type = F_UNLCK; fcntl(fd, F_SETLK, &fl); } return 0;

Los programas Escritor.c y Lector.c estn pensados para ser ejecutados de manera simultanea. En principio, podrn existir simultaneamente tantos procesos escritores y lectores como queramos. Ejecute la siguiente secuencia. Primero creamos el archivo BD (que estar vacio) y a continuacin lanzamos la ejecucin simultanea de 3 procesos lectores y dos procesos escritores.
alumno@maquinaLinux~/PracticasAnalisis/ModuloSinCom$ > BD alumno@maquinaLinux~/PracticasAnalisis/ModuloSinCom$ ./Lector & ./Escritor & ./Lector & ./Escritor & ./Lector ...

MODELO CLIENTE SERVIDOR


Este modelo de interaccin entre procesos concurrentes resuelve el problema de acceder a un recurso gestionado por un proceso gestor (servidor), local o remoto. En el modelo cliente-servidor, este ltimo es el encargado de proporcionar acceso a un servicio y por tanto de gestionar el acceso al/los recursos. El cliente acceder al servicio proporcionado por el servidor siguiendo un protocolo de peticin-respuesta. Para comprobar el funcionamiento del modelo cliente-servidor, se han diseado dos programas: TCP_s.c y TCP_c.c que se corresponden con la aplicacin servidor y cliente respectivamente. A continuacin se muestra el cdigo de la aplicacin TCP_s.c
TS-01.TS-02.TS-03.TS-04.TS-05.#define MYNAME "TCP_s" #include <arpa/inet.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <sys/socket.h>

TS-06.TS-07.TS-08.TS-09.TS-10.TS-11.TS-12.TS-13.TS-14.TS-15.TS-16.TS-17.TS-18.TS-19.TS-20.TS-21.TS-22.TS-23.TS-24.TS-25.TS-26.TS-27.TS-28.TS-29.TS-30.TS-31.TS-32.TS-33.TS-34.TS-35.TS-36.TS-37.TS-38.TS-39.TS-40.TS-41.TS-42.TS-43.TS-44.TS-45.TS-46.TS-47.TS-48.TS-49.TS-50.TS-51.TS-52.TS-53.TS-54.TS-55.TS-56.TS-57.TS-58.TS-59.TS-60.TS-61.TS-62.TS-63.TS-64.TS-65.TS-66.TS-67.-

#include #include #include #include #include #include #include #include #include

<sys/types.h> <sys/un.h> <sys/wait.h> <netdb.h> <ctype.h> <signal.h> <stdio.h> <stdlib.h> <unistd.h>

void Timeout_Control(int signo) { int timeout; char * text = "TIMEOUT!...Terminating now.\n"; if (!signo) { text = getenv("TIMEOUT"); if (text) { signal(SIGALRM, Timeout_Control); timeout = atoi(text); if (timeout >= 0) alarm(timeout); } } else { write(2, text, strlen(text)); exit(0); } } void SIGCHLD_Handler(int signo) { signal(SIGCHLD, SIGCHLD_Handler); if (signo == SIGCHLD) waitpid(-1, NULL, WNOHANG); } int main(int argc, char * argv[]) { int sd, cd, size, ret; char ch; short int port; struct sockaddr_in s_ain, c_ain; Timeout_Control(0); SIGCHLD_Handler(0); sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sd == -1) perror(argv[0]); if (argc > 1) else port = atoi(argv[1]); port = 7777;

bzero((char *) &s_ain, sizeof(s_ain)); s_ain.sin_family = AF_INET; s_ain.sin_addr.s_addr = INADDR_ANY; s_ain.sin_port = htons(port); /* 7 == echo port */ ret = bind(sd, (struct sockaddr *) &s_ain, sizeof(s_ain)); if (ret == -1) perror(argv[0]);

TS-68.listen(sd, 5); TS-69.while (1) TS-70.{ TS-71.size = sizeof(c_ain); TS-72.cd = accept(sd, (struct sockaddr *) &c_ain, &size); TS-73.switch (fork()) TS-74.{ TS-75.case -1: TS-76.perror("echo server"); TS-77.return 1; TS-78.case 0: TS-79.close(sd); TS-80.while (recv(cd, &ch, 1, 0) == 1) TS-81.{ TS-82.ch = toupper(ch); TS-83.send(cd, &ch, 1, 0); TS-84.} TS-85.close(cd); TS-86.return 0; TS-87.default: TS-88.close(cd); TS-89.} /* switch */ TS-90.} /* while */ TS-91.- } /* main */

Compile el programa TCP_s.c y ejecutelo en segundo plano (background).


alumno@maquinaLinux:~/PracticasAnalisis/ModuloSinCom$ ./TCP_s 18231 & [1234]

En este ejemplo se utiliza el argumento 18231 para lanzar el proceso servidor, pero puede utilizar otros valores.

Utilizaremos el programa TCP_c.c como proceso cliente. Este programa puede recibir dos parmetros, uno o ninguno. Realice un par de conexiones interactivas con su servidor, desde la mquina local. Y compruebe el funcionamiento del modelo cliente-servidor.

alumno@maquinaLinux:~/PracticasAnalisis/ModuloSinCom$ ./TCP_c 127.0.0.1 18231 Hola, qu tal? ^D

Si se est trabajando en la mquina triqui.fi.upm.es, a travs de varios terminales putty, asegrese que en ambos terminales estn conectado al mismo nodo (triqui3 o triqui4). Recuerde que hemos arrancado el programa servidor como un demonio, esto es, en segundo plano y a la escucha en un canal de comunicacin con direccin conocida. Para evitar que se nos quede este proceso latente en el sistema (consumiendo el puerto al que est asociado) deberemos matarlo.

Ejecute el mandato fg, para traerlo a primer plano y luego ^C para matarlo.
alumno@maquinaLinux:~/PracticasAnalisis/ModuloSinCom$ fg ./TCP_s 18231 ^C [1234] Interrupted

O bien, consulte su PID con un ps y luego lncele una seal con el mandato kill.
alumno@maquinaLinux:~/PracticasAnalisis/ModuloSinCom$ kill -9 1234 [1234] Killed

Intentemos ahora medir las prestaciones de este tipo de comunicacin local. Cree y tenga a mano un fichero de 1 Mega byte (por ejemplo, puede utilizar el programa Robot_B que se utiliz en el mdulo de ficheros). Veremos cuanto tiempo (aproximado) tarda en trasferirse en ida y vuelta este fichero. Para medir el tiempo utilizaremos el mandato Times_C.
alumno@maquinaLinux:~/PracticasAnalisis/ModuloSinCom$ ./Times_C ./TCP_c 127.0.0.1 18231 < 1MB.dat > /dev/null Times_C: Real:X.xxx" User:XX.xxx" Syst:XX.xxx"

Intentemos ahora medir las prestaciones de la comunicacin remota. Busque una mquina remota donde pueda compilar y ejecutar el servidor TCP (digamos que se llama triqui.fi.upm.es). Lncelo en dicha mquina remota y desde la mquina local (que debe ser otra), desde la que est realizando ests prcticas, vuelva a contactar y a medir el tiempo de transferir un megabyte.

alumno@maquinaLinux:~/PracticasAnalisis/ModuloSinCom$ triqui.fi.upm.es 18231 <1MB.dat >/dev/null Times_C: Real:X.xxx" User:XX.xxx" Syst:XX.xxx"

Times_C

./TCP_c

No olvide terminar los procesos servidores que haya arrancado. De otro modo no podrn arrancar otro en el mismo puerto.