#include
#include
#include
#include
#include
#include
#define MAXLON 1000
void*cuenta(void*dato){
int pos, cont=0, leidos;
char*nombre=(char*)dato,cadena,MAXLON))!=0)
int fd;
while((leidos=read(fd,cadena,MAXLON))!=0)
for(pos=0; pos
if((cadena[pos]=='a') ||(cadena[pos]=='A'))
cont++;
printf("fichero %s:%d caracteres 'a' o 'A' encontramos" nombre,cont);
close(fd);
pthread_exit(NULL);
}
int main(int argc,char*argv[]){
pthread_t hilo;
printf("indica el nombre de un fichero.");
exit(0);
}
pthread_create(&hilo,NULL,cuenta,(void*) argv[1]);
pthread_join(hilo,NULL);
return 0;
}
miércoles, 21 de diciembre de 2011
jueves, 1 de diciembre de 2011
PRACTICA POLICIA
55. Disponemos de un disco duro de 20 GB de capacidad. Hay establecida sobre él, una única partición que contiene un sistema de ficheros del tipo FAT32 en el que cada agrupamiento (cluster) consta de 16 sectores de 512 bytes cada uno. ¿Cuántos sectores del disco se necesitarán para almacenar cada copia la FAT? Razona tu respuesta.
En primer lugar se calcula lo que ocupa la FAT, que es el tama˜no del enlace (32 bits) por el n´umero de entradas de la tabla que, a su vez, es el tama˜no del disco dividido por el tama˜no del agrupamiento y que en este problema son 20GB/(16 ∗ 512bytes) = 20 ∗ 217 entradas. Luego la tabla ocupa 20 ∗ 217 ∗32bits = 20 ∗ 219bytes. Si se divide lo que ocupa la tabla por el tama˜no del agrupamiento se obtiene el n´umero de agrupamientos que ocupa la tabla: 20 ∗ 219/(16 ∗ 512) = 20 ∗26 = 1280agrupamientos, que multiplicado por 16, que es el n´umero de sectores por agrupamiento, se obtiene el n´umero total de sectores que es 20480.
56. La policía ha arrestado al sospechoso de un delito. Al analizar el contenido de su ordenador piensan que pueden inculparle pues el contenido del mismo es el siguiente:
En un sistema de archivos FAT, los bloques se asignan como una lista enlazada que finaliza con la posici´on fin de lista EOF. Es posible recuperar datos utilizando los enlaces partiendo desde esa posici´on EOF hacia atr´as.
La reconstrucci´on de la lista de bloques ser´a:
14 → 15 → 12 → 13 → 10 → 11 → EOF
La informaci´on de esa lista de bloques ser´a: sigan → buscando → yo → no → he → sido → EOF
Número De bloque de datos | Contenido |
10 | he |
11 | sido |
12 | yo |
13 | no |
14 | sigan |
15 | buscando |
Como experto informático, pides consultar el contenido de la FAT, que es el siguiente:
Número de entrada en la FAT | Contenido |
10 | 11 |
11 | EOF |
12 | 13 |
13 | 10 |
14 | 15 |
15 | 12 |
#include
#include
#include
#include
#include
#include
#define MAX 10
#define FIN -1
int buffer[MAX];
sem t huecos, elementos;
int generar dato (void) { return random() %256;} int numero aleatorio(void) { return random() %100;}
void ∗productor (void ∗p) {
int pos productor= 0;
int num, dato, n;
n= numero aleatorio();
printf ("Productor con %d datos\n", n);
for(num= 0; num< n; num++) { dato= generar dato();
sem wait (&huecos);
buffer[pos productor]= dato;
pos productor= (pos productor+ 1) %MAX;
sem post (&elementos);
}sem wait (&huecos);
buffer[pos productor]= FIN;
sem post (&elementos);
pthread exit (NULL);
}oid ∗consumidor(void ∗p){
int pos consumidor= 0, dato;
bool continuar= true;
while (continuar) { sem wait (&elementos);
dato= buffer[pos consumidor];
sem post (&huecos);
if (dato== FIN)
continuar= false;
else { printf ("Numero aleatorio: %d\n", dato);
pos consumidor= (pos consumidor+1) %MAX;
}
}
pthread exit (NULL);
int main (int argc, char ∗argv[]) {
pthread t hiloproductor, hiloconsumidor;
sem init (&elementos, 0, 0);
sem init (&huecos, 0, MAX);
pthread create (&hiloproductor, NULL, productor, NULL);
pthread create (&hiloconsumidor, NULL, consumidor, NULL);
pthread join (hiloproductor, NULL);
pthread join (hiloconsumidor, NULL);
sem destroy (&huecos);
sem destroy (&elementos);
return 0;
jueves, 24 de noviembre de 2011
JERARQUIA DE PROCESOS RESULTANTE
Estudia el siguiente codigo y escribe la jerarquia de procesos resultante.
Despues, compila y ejecuta el codigo para comprobarlo (deberas añadir llamadas al sistema getpid, getppid y wait para conseguirlo).
wait que cambia el estado del proceso padre a bloqueado hasta que el proceso hijo termine.
PUBLICADO Ma. Isabel wait, que hace que el proceso padre pase a estado bloqueado hasta que un proceso hijo termine, se encuentra dentro de un bucle que va a hacer que se llame tantas veces como procesos hijos creo.
Despues, compila y ejecuta el codigo para comprobarlo (deberas añadir llamadas al sistema getpid, getppid y wait para conseguirlo).
Se observa que los procesos terminan en el orden contrario al que se han creado, es decir, primero termina el ´ultimo proceso creado y el ´ultimo proceso en terminar es el inicial. Esto ocurre gracias a la llamada al sistema
Se observa que el proceso padre es siempre el ´ultimo en terminar. Esto es debido a que la llamada al sistema
PUBLICADO Ma. Isabel wait, que hace que el proceso padre pase a estado bloqueado hasta que un proceso hijo termine, se encuentra dentro de un bucle que va a hacer que se llame tantas veces como procesos hijos creo.
miércoles, 23 de noviembre de 2011
ACTIVIDAD 1
Dibuja la jerarquía de procesos que resulta de la ejecución del siguiente código. Introduce las llamadas al sistema wait para que una vez generado el árbol de procesos los hijos sean esperados por sus respectivos padres. Ademas, haz que se informe de los tiempos de ejecución de las aplicaciones xload y kcalc que se generen así como del tiempo total de ejecución. Para calcular el tiempo transcurrido, puedes utilizar la función´ time() de la librería estándar time.h. La llamada time(NULL) devuelve los segundos transcurridos desde las 00:00:00 del 1/1/1970 hasta el instante de la llamada.
Código:
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main (int argc, char *argv[]) {
int i, j;
pid_t pid, nuevo, nuevo1;
time_t ini, fin;
ini = rand()%25+1;
for (i= 0; i< 2; i++)
{ pid= getpid();
for (j= 0; j< i+2; j++)
{ nuevo= fork();
if(nuevo== 0){ break;
nuevo1= fork();
if(nuevo1== 0)
execlp ("xload", "xload", NULL);
}
}
if (pid!= getpid())
execlp ("kcalc", "kcalc", NULL);
}
for (i= 0; i< 2; i++)
for (j= 0; j< i+2; j++){ wait(NULL);
printf ("Tiempo en ejecucion de kcalc: %ld\n", (rand()%50+1)-ini);
}
printf ("Tiempo total: %ld\n", (rand()%25+1)-ini);
return 0;
}
Código:
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main (int argc, char *argv[]) {
int i, j;
pid_t pid, nuevo, nuevo1;
time_t ini, fin;
ini = rand()%25+1;
for (i= 0; i< 2; i++)
{ pid= getpid();
for (j= 0; j< i+2; j++)
{ nuevo= fork();
if(nuevo== 0){ break;
nuevo1= fork();
if(nuevo1== 0)
execlp ("xload", "xload", NULL);
}
}
if (pid!= getpid())
execlp ("kcalc", "kcalc", NULL);
}
for (i= 0; i< 2; i++)
for (j= 0; j< i+2; j++){ wait(NULL);
printf ("Tiempo en ejecucion de kcalc: %ld\n", (rand()%50+1)-ini);
}
printf ("Tiempo total: %ld\n", (rand()%25+1)-ini);
return 0;
}
jueves, 27 de octubre de 2011
PRACTICAS 1-15
Practica 1 Matando un proceso en modo grafico
Practica 2 Matando un proceso por línea de comandos
Practica 3 Matando un proceso por medio de scripts
Practica 4 Ver los procesos de usuario desde línea de comandos
Practica 5 Mostrando los porcentajes de uso de memoria de los procesos
Practica 6 Ejecución de procesos de manera concurrente
Prac7 Uso del comando jobs (viendo estado de procesos)
Practica 8 Pausar tareas y 9 Muestra de reinicio de procesos
Practica 10 Crear una lista FIFO
Practica 11 Agregando un proceso a una lista FIFO
Practica 12 Creado listas con mknod
Practica 13 Observar listas de procesos creadas hasta ahora
Practica14 Eliminando una lista
Practica 15 Ver árbol de procesos
jueves, 20 de octubre de 2011
PRACTICA SEMAFOROS
lock_lp (tipo_flag flag)/*solicita ejecutar la seccion critica*/
{
BOOL entrar= 0;
while (!entrar)
{
lock(cerrojo_flags);
if (flag)
{
unlock(cerrojo_flags);
dormir(flag);
}
else
{
entrar= 1;
flag= 1;
unlock(cerrojo_flags);
}
}
}
{
BOOL entrar= 0;
while (!entrar)
{
lock(cerrojo_flags);
if (flag)
{
unlock(cerrojo_flags);
dormir(flag);
}
else
{
entrar= 1;
flag= 1;
unlock(cerrojo_flags);
}
}
}
unlock_lp (tipo_flag flag)/*otro proceso puede ejecutar la seccion critica*/
{
lock(cerrojo_flags);/*Una sección crítica se protege*/
flag= 0;
despertar(flag);
unlock(cerrojo_flags);
}
{
lock(cerrojo_flags);/*Una sección crítica se protege*/
flag= 0;
despertar(flag);
unlock(cerrojo_flags);
}
El codigo de la Figura 2.15 representa una implementacion para un
multiprocesador de las primitivas de exclusion mutua de largo plazo basadas en
dormir y despertar.
(a) Analizar la estructura de las secciones criticas que contienen.
/*Un evento se implementa mediante una variable booleana o flag
y la cola asociada de procesos bloqueados en él. Los procesos que
ejecutan dormir sobre un flag activado pasan a estado bloqueado,
provocando un cambio de contexto. Cuando otro proceso o el propio
sistema operativo ejecuta despertar sobre ese flag, desbloquea a todos
los procesos dormidos en ese flag.
*/
(b) Siguiendo esta misma idea, dados los algoritmos de las primitivas de bajar y subir
sobre semaforos estudiadas, re-implementar bajar y subir sobre semaforos.
Subir () puede encargarse de liberar los cerrojos de los procesos, y bajar() de restaurarlos. En otras palabras, los procesos en estado bloqueado se consideran fuera de toda sección crítica. Un problema del esquema subir/bajar es que bajar desbloquea a todos los procesos subidos en el flag y sólo uno de ellos accederá a la sección crítica. Esto es especialmente preocupante en multiprocesadores, ya que producirían contención en el acceso al cerrojo. Sin embargo, la limitación fundamental del manejo de eventos con este mecanismo deriva de que la primitiva de bajar no almacena el evento; lo que introduce la posibilidad de condiciones de carrera en una secuencia de subir y bajar sobre un flag (importa el orden en que se ejecutan).
p wait espera
v señal.
p wait espera
v señal.
Publicado por : Ma. Isabel Serrano Medina
miércoles, 12 de octubre de 2011
DIFERENCIA DE LIFO Y FIFO
DIFERENCIA DE FIFO Y LIFO
FIFO: (First In, First Out), que son las colas.
Colas simples:
Se inserta por un sitio y se saca por otro, en el caso de la cola simple se inserta por el final y se saca por el principio. Para gestionar este tipo de cola hay que recordar siempre cual es el siguiente elemento que se va a leer y cual es el último elemento que se ha introducido.
Colas circulares:
En las colas circulares se considera que después del último elemento se accede de nuevo al primero. De esta forma se reutilizan las posiciones extraídas, el final de la cola es a su vez el principio, creándose un circuito cerrado.
LIFO: (Last In, First Out), que son las pilas.
Las pilas son estructuras de datos que tienes dos operaciones básicas:
push (para insertar un elemento) y pop (para extraer un elemento). Su característica fundamental es que al extraer se obtiene siempre el último elemento que acaba de insertarse.
Las pilas se utilizan en muchas aplicaciones que utilizamos con frecuencia. Por ejemplo, la gestión de ventanas en Windows (cuando cerramos una ventana siempre recuperamos la que teníamos detrás). Otro ejemplo es la evaluación general de cualquier expresión matemática para evitar tener que calcular el número de variables temporales que hacen falta. Por ejemplo:
3 + 4 * (8 – 2 * 5)
martes, 4 de octubre de 2011
EXAMEN
Implemente utilizando semáforos una solución a esta variante del problema de los filósofos. Hay F filósofos (F mayor o igual que cinco); y hay P palillos, que se pueden tomar en cualquier orden (no están ordenados circularmente en la mesa). Cuando un filósofo quiere comer, coge un par de palillos cualesquiera y cuando acaba de comer, los devuelve a la mesa.
#include "rshmem.h"
#include <stdlib.h>
#include <sys/sem.h>
#include <math.h>
#include <time.h>
#define N 5 /* tomo 5, como un numero generico de filosofos */
#define M 50 /* numero total de veces que comen los filosofos *
/* Declaracion de la funcion incrementa */
incrementa (int *mem, int k){
int i;
i=*mem;
TP ; TP ; TP TP ;TP ; TP TP ; TP ; TP TP ; TP ;
TP i=i+k;TP ; TP ; TP TP ;TP ; TP TP ; TP ; TP TP ;
TP ; TP
*mem=i;
}
/* Declaracion de la funcion filosofo: uso de semaforos */
filosofo(FILE *pf, key_t *sclave, int *sfilo, int i, int *comer, int *fin, int *fc){
/* ABRIR SEMAFOROS */
/*Abrir semaforo del filosofo de la izquierda del que desea comer */
if (-1==(sfilo[i]=semOpen(sclave[i])))
fprintf(stderr,"no tengo el cualificador del semaforo filosofo %d\n",i);
/*Abrir semaforo del filosofo de la derecha del que desea comer */
if (-1==(sfilo[(i+2)%N]=semOpen(sclave[(i+2)%N])))
fprintf(stderr,"no tengo el cualifacador semaforo filosofo %d\n",(i+2)%N);
while(*comer<M){
semWait(sfilo[i]);
(*fc)++;
if (*fc>(N+1)/2) /* mira si mas de la mitad de los filosofos estan intentando comer */
{
semSignal(sfilo[i]);
(*fc)--;
}
else {
semWait(sfilo[(i+2)%N]);
incrementa(comer,1);
(void) fprintf(pf,"[comer:%.2d] el filosofo %d ha comido\n", *comer, (i+1)%N);
fflush(pf); /* para sincronizar la escritura de datos en el fichero de salida */
semSignal(sfilo[(i+2)%N]);
semSignal(sfilo[i]);
(*fc)--;
}
}semClose(sfilo[i]);
semClose(sfilo[(i+2)%N]);
(*fin)++;
exit(1);
}
int main(){
FILE *pf; /* puntero a fichero salida */
key_t sclave[N+1]; /* array de claves para semaforos */
int sfilo[N]; /* un semaforo por filosofo */
int *comer; /* variable de memoria compartida */
int *fin; /* variable de memoria compartida */
int *fc; /* variable de memoria compartida */
int i; /* contador */
printf("1");
if((pf=fopen("fich", "w+"))==NULL){
fprintf(stderr,"error al abrir el fichero para salidas\n");
exit(-1);
}
printf("abre fichero salida");
for(i=0; i<N; i++){
printf("el for ");
/*crear nombres claves filosofos */
if((key_t)-1==(sclave[i]=ftok("filos",'s'+i))){
fprintf(stderr,"main: error crear clave filosofo %d con ftok(%c)\n", i,'s'+i);
exit(1);
}
/*crear semaforos filosofos */
print("dentro del fo");
if(-1==(sfilo[i]=semCreate(sclave[i],1))){
fprintf(stderr,"main: no pude crear semaforo filosofo %d\n",i);
exit(1);
}
}
printf("hola");
if(!crearMemoria())
fprintf(stderr,"error de crearMemoria()\n");
/*inicializar variable comer y variable fin */
comer = (int *) memoria;
*comer = 0;
fin = (int *) comer + sizeof(int);
*fin = 0;
fc = (int *) comer + sizeof(int);
for(i=0; i<N; i++){
if(0==fork()) /* PROCESOS HIJOS */
filosofo(pf, sclave, sfilo, i, comer, fin, fc);
}
while(*fin<5); /*espera a que los filosofos coman M veces */
fprintf(pf,"no habia comido ningun filososo y ahora han comido %d", *comer);
fclose(pf); /* eliminar memoria de las variables compartidas */
if(!eliminarMemoria())
fprintf(stderr,"error de eliminarMemoria()\n");/* cerrar semaforos */
for(i=0; i<N; i++)
semClose(sfilo[i]);
exit(0);
} /*fin proceso padre, fin main */
domingo, 2 de octubre de 2011
miércoles, 28 de septiembre de 2011
POSIX
POSIX: Portable Operating System Interface (IEEE)
El término fue sugerido por Richard Stallman en respuesta a la demanda de la IEEE, que buscaba un nombre fácil de recordar. Una traducción aproximada del acrónimo podría ser “Interfaz para Sistemas Operativos migrables basados en UNIX”.
Estos son una familia de estándares de llamadas al sistema operativo definidos por el IEEE y especificados formalmente en el IEEE 1003. Persiguen generalizar las interfaces de los sistemas operativos para que una misma aplicación pueda ejecutarse en distintas plataformas. Estos estándares surgieron de un proyecto de normalización de las API y describen un conjunto de interfaces de aplicación adaptables a una gran variedad de implementaciones de sistemas operativos.
Especifica las interfaces de usuario y software al sistema operativo en 15 documentos diferentes. La línea de comandos estándar y las interfaces de scripting se basaron en Korn Shell. Otros programas a nivel de usuario (user-level), servicios y utilidades incluyen AWK, echo, ed y cientos de otras. Los servicios a nivel de programa requeridos incluyen definición de estándares básicos de I/O, (file, terminal, y servicios de red). También especifican una API para las bibliotecas de threading, que es muy utilizada en una gran variedad de sistemas operativos.serrano me
jueves, 22 de septiembre de 2011
PRACTICA 3 Y 4
CODIGO PID 1450
#include <sys/types.h>#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define NUM_HIJOS 3
int main (void)
{
int ret,i;
for(i=0;i<NUM_HIJOS;i++)
{
ret=fork();
if(ret==0)
{
printf("Yo soy el hijo %d, mi padre es PID=%d, yo soy PID=%d \n",i,getpid(),getpid());
}
else if (ret>0)
{
ret=wait(NULL);
while(ret>0)
{
ret=wait(NULL);
}
}
if(ret==-1 && errno!=ECHILD)
{
perror("Falo en WAIT");
exit(EXIT_FAILURE);
exit(EXIT_SUCCESS);
}
else if(ret==-1)
{
perror("Fallo en Fork");
exit(EXIT_FAILURE);
}
}
}
PRACTICA 4
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define NUM_HIJOS 2
int main (void)
{
int ret,i;
for(i=0;i<NUM_HIJOS;i++)
{
ret=fork();
if(ret==0)
{
printf("Yo soy el hijo %d, mi padre es PID=%d, yo soy PID=%d y mi hijo es %d\n",i,getpid(),getpid(),
getppid());
}
else if (ret>0)
{
ret=wait(NULL);
while(ret>0)
{
ret=wait(NULL);
}
}
if(ret==-1 && errno!=ECHILD)
{
perror("Fallo en WAIT");
exit(EXIT_FAILURE);
exit(EXIT_SUCCESS);
}
else if(ret==-1)
{
perror("Fallo en Fork");
exit(EXIT_FAILURE);
}
}
}
{
int ret,i;
for(i=0;i<NUM_HIJOS;i++)
{
ret=fork();
if(ret==0)
{
printf("Yo soy el hijo %d, mi padre es PID=%d, yo soy PID=%d y mi hijo es %d\n",i,getpid(),getpid(),
getppid());
}
else if (ret>0)
{
ret=wait(NULL);
while(ret>0)
{
ret=wait(NULL);
}
}
if(ret==-1 && errno!=ECHILD)
{
perror("Fallo en WAIT");
exit(EXIT_FAILURE);
exit(EXIT_SUCCESS);
}
else if(ret==-1)
{
perror("Fallo en Fork");
exit(EXIT_FAILURE);
}
}
}
Publicado por Ma. Isabel Serrano Medina 1701
miércoles, 21 de septiembre de 2011
PRACTICA ARBOLES
1.¿POR QUE APARECEN MENSAJES REPETIDOS?
R=para que muestren mensajes repetidos el truco es aprovechar que la función fork, que permite crear nuevos procesos, copia todo el proceso del llamador. Y eso incluye a los del pipe, pero el pipe no se duplica Y esto da como resultado que si el padre escribe p(1) que el hijo puede leer en p[0], o viceversa, es decir es un metodo de conexion de que une la salida estandar de un proceso a la entrada estandar de otro.
2.- ¿QUE OBSERVAS?
R=que no es necesario esperar a que el primer proceso termine de procesar para que el otro comience es decir son procesos completamente independientes y corren al mismo tiempo
R=que no es necesario esperar a que el primer proceso termine de procesar para que el otro comience es decir son procesos completamente independientes y corren al mismo tiempo
3.- ¿POR QUE?
Un pipe puede ser más útil en el caso de comunicar un proceso padre con un proceso hijo y se pueden usarse para leer y escribir en bytes
Un pipe puede ser más útil en el caso de comunicar un proceso padre con un proceso hijo y se pueden usarse para leer y escribir en bytes
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main (void)
{
/**ATENCIÓN: Declaración de variables del programa a probar. Es sólo un exemplo**/
int i;
int n = 4;
int childpid;
/**El resto de variables son para que la presentación de los resultados por pantalla sea posible**/
int a, p;
int ret;
FILE *fpipe; // listo para leer los bytes que emergen del pipe
char comanda[50];
/*String dónde se guarda el comando a ejecutar por el 1r hijo*/
char line[256];
p = getpid();
sprintf(comanda,"pstree -n -p %d\n",getpid());
/*Concatenamos el comando pstree con el pid del padre*/
ret = fork();
if (ret == 0) { /*Este es el primer hijo del padre*/
if ( !(fpipe = (FILE*)popen(comanda,"r")) ) /* Lo de pclose no es un error de tipeo. Si un "stream" se abre con popen, se cierra solamente con pclose. Esto es así porque esta función se ocupa no sólo de cerrar en pipe sino de hacer las limpiezas relacionadas con el haber creado un proceso hijo*/
{ /* Si el pipe falla*/
perror("Problemas con el pipe!!!");
exit(1);
}
while ( fgets( line, sizeof line, fpipe))
{
printf("%s", line); /*Escribimos por pantalla lo que retorna el hijo. La salida del pstree*/
}
pclose(fpipe);
} else {
/*El primer hijo sólo se crea para hacer un pstree y poder ver por pantalla */
/*el árbol de procesos generado*/
/*El código que viene a continuación, lo podéis substituir por lo que se tercie*/
/*¡¡Las variables han de ir declaradas arriba!!!*/
for (i = 1; i < n; i++) {
if ((childpid = fork()) == -1) {
break;
}
fprintf(stderr, "Este es el proceso %ld com padre %ld\n", (long)getpid(), (long)getppid());
}
sleep(1); /*Es sólo para dar tiempo a terminar a todos los hijos*/
}exit(0);}
Publicado por Maria Isabel Serrano Medina
Suscribirse a:
Entradas (Atom)