|
*****************************************
P1
*****************************************
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> #include <time.h>
//Funcion que lee y debe mostrar el contenido de un directorio //le pasamos por parametro el nombre de dicho archivo
void Lectura(char *narchivo)
{ int cerrar=0; DIR* open=NULL; struct dirent* dirp; open=opendir(narchivo); //abrimos un flujo de directorio. printf("El contenido de este directorio es: \n");
while((dirp=readdir(open))!=NULL) { //Recorremos el flujo de directorio imprimiendo los nombres de archivos en el contenidos. printf("\n * %s \n",dirp->d_name);
}
cerrar=closedir(open); //cerramos el flujo de directorio.
}
//funcion muestra el tipo de archivo y sus atributos, le pasamos //por parametro el nombre de dicho archivo
void Tipo(char* narchivo){ int a=0; int arch=0; struct stat buffer; //Declaro buffer como una estructura tipo stat. //Con esto lo que hacemos es almacenar en buffer las caracteristicas del archivo. a=lstat(narchivo,&buffer); //Realizamos un and logico entre la mascara y el contenido del campo st_mode arch=(buffer.st_mode)&S_IFMT; //Comparamos el resultado anterior con las banderas de cada tipo de archivo //y gracias a este switch podremos saber de que tipo de archivo se trata. switch (arch)
{ case (S_IFIFO):
printf("\nEs un Archivo FIFO \n\n"); break;
case (S_IFDIR):
printf("\nEs un Directorio\n\n"); Lectura(narchivo); break;
case (S_IFREG):
printf("\nEs un Archivo Regular\n\n"); break;
case (S_IFLNK):
printf("\nEs un Enlace Simbólico\n\n"); break;
case (S_IFBLK):
printf("\nEs un Dispositivo de bloques\n\n"); break;
case (S_IFCHR):
printf("\nEs un Dispositivo de Caracteres\n\n"); break;
default:
printf("\nEs un fichero desconocido\n\n"); break;
}
//Mostramos por pantalla las principales caracteristicas printf("\n");
printf("Nº de i-nodo: %d \n",buffer.st_ino);
printf("Tamaño total en bytes: %d\n",buffer.st_size);
printf("Nº de bloques asignados: %d\n",buffer.st_blocks);
printf("Usuario al que pertenece: %d\n",buffer.st_uid);
printf("Fecha última modificación: %s",asctime(localtime(&buffer.st_mtime)));
printf("Fecha último cambio: %s",asctime(localtime(&buffer.st_ctime))); printf("\n******************************************************************\n\n");
}
//Programa Principal main(int argc, char *argv[]) {
int i=0; if(argc==1) { //Mensaje en el caso de que no se introduzcan parámetros por la línea de comandos. printf("No se ha introducido parámetro, a continuación se detalla como debe hacerse: \n './info <ruta1> <ruta2>'...... \n ");
}
else { printf("\n************ Práctica: El Sistema de Archivos de Linux ***********"); //Imprimo por pantalla el nombre del archivo o la ruta si es un directorio. printf("\n\nNombre de archivo o ruta completa (si se trata de un directorio):\n %s\n",argv[1]);
for(i=1;i<argc;i++) {
Tipo(argv[i]); //Llamo a la función tipo para obtener el tipo de archivo que es.
}
}
} *****************************************
P2
*****************************************
#include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <unistd.h> #include <signal.h>
void* obtiene_ident(void *p) //Con esta función vamos a obtener el identificador de proceso (PID) //tanto del proceso padre como del proceso hijo. { pid_t pidp; pid_t pidh; char *com; com=(char *)p; pidp=getpid(); int est; pidh=fork();
if (pidh==0) //Si la función fork() devuelve 0 es que el proceso hijo se //ha creado correctamente. { printf("\n\nSe ha creado con éxito el proceso hijo\n\n"); printf("El comando a ejecutar es: %s\n",com); printf("El PID del proceso hijo es: %d\n",getpid()); printf("El PID del proceso padre es: %d\n\n",pidp);
//Con esta función vamos a ejecutar el comando. execvp(com,NULL);
//Ahora vamos a hacer que termine el proceso hijo. exit(getpid()>pidp);
} else { //a waitpid() la invoca nuestro programa (el padre) y entonces éste tiene que // que esperar a que acabe su hijo
while( waitpid(pidh,&est,0) != pidh);//esperamos a que el proceso hijo haya finalizado //La llamada waitpid proporciona un método para esperar por un hijo en particular. //Tiene tres parámetros. Si pid es igual a -1, waitpid espera por cualquier proceso. //Si pid es positivo entonces espera al hijo cuyo PID es pid. }
}
int main (int argc,char *argv[])
{
printf("\n******************************************************************\n"); printf("\n*********************Práctica 2: Procesos*************************"); printf("\n******************************************************************\n");
int i = 0;
if(argc<2) {
//comprobamos si se han introducido parámetros,sino no se ha hecho //se imprime en pantalla un mensaje de error.
printf("\n\nNo se ha introducido ningún parámetro de entrada\n\n"); printf("Hágalo de esta manera: ejecutaOrdenes <comando1> <comando2>....\n\n"); printf("\n******************************************************************\n");
} else {//tenemos argumentos suficientes para empezar la ejecucion de las rutinas for(i=1;i<argc;i++) //Con este bucle consigo que se ejucute la función { //tantas veces como comandos se introducen por teclado. obtiene_ident(argv[i]);
} exit(0);
}
} *****************************************
P3
*****************************************
#include "libreria.h"
//A continuación pasamos a implementar el programa principal.
main(int argc, char *argv[]) {
printf("\n************* Práctica 3 ****************\n"); printf("\n***** Programación con hebras POSIX *****\n");
int tmatriz=atoi(argv[1]); //Con la función atoi transformo en valores enteros los caracteres int semilla=atoi(argv[2]);//que recibo por teclado y que indican el tamaño de la matriz y la semilla.
int i=0; int j=0; int n=0;
int matr1[tmatriz][tmatriz]; // int matr2[tmatriz][tmatriz]; //Reservo espacio para las matrices int matresult[tmatriz][tmatriz]; //
int numaleat=0; int numhebras=(tmatriz*tmatriz);//De esta manera almacena en esta variable el nº de hebras a crear. struct hebestandar hebra[numhebras];//Declaro esta estructura en la que están los parámetros de cada hebra. //Voy a rellenar las matrices con valores enteros aleatorios
srand(semilla);//Con esta función los números generados serán distintos en cada ejecución de mi programa //ya que se generan a partir de la variable semilla que se introduce por la linea de comandos.
for (i=0;i<tmatriz;i++) { for (j=0;j<tmatriz;j++)
{
numaleat=(rand()%10); matr1[i][j]=numaleat; //Las matrices 1 y 2 las relleno con valores aleatorios matr2[i][j]=numaleat; //generados a partir de una semilla y la matriz de resultados matresult[i][j]=0; //la inicializo a cero de momento.
}
} //Asignación de filas y columnas de la matriz resultado para cada hebra, es decir, asigno a la hebra 0 el elemento 0 de //la matriz resultado (fila 0, columna 0), a la hebra 1 el elemento 1 (fila 0, columna 1) y así de manera sucesiva.
for (i=0;i<tmatriz;i++) { for (j=0;j<tmatriz;j++)
{
hebra[n].fila=i; hebra[n].columna=j; n++;
} } //Ahora vamos a reservar espacio en memoria para los punteros que apuntan a las matrices que utilizan las hebras.
for (n=0;n<numhebras;n++) {
hebra[n].matr1=(int **)malloc(sizeof(int *)*tmatriz); hebra[n].matr2=(int **)malloc(sizeof(int *)*tmatriz); for (i=0;i<tmatriz;i++)
{
hebra[n].matr1[i]=(int *)malloc(sizeof(int)*tmatriz); hebra[n].matr2[i]=(int *)malloc(sizeof(int)*tmatriz); }
} //Aquí lo que vamos a hacer es asignar a los punteros de cada hebra que apuntan a las matrices los valores correspondientes a las matrices 1 y 2 que anteriormente hemos llenado con valores aleatorios.
for (n=0;n<numhebras;n++) { for (i=0;i<tmatriz;i++)
{ for (j=0;j<tmatriz;j++)
{
hebra[n].matr1[i][j]=matr1[i][j]; hebra[n].matr2[i][j]=matr2[i][j]; }
}
hebra[n].numident=n; //En las variables numident y xtam de cada hebra almaceno hebra[n].xtam=tmatriz;//el numero de cada hebra y el tamaño de la matriz respectivamente.
} //Inicializo el semáforo y la variable donde vamos a guardar el resultado final.
sem_init(&semaforo,0,1); //El 0 indica que que el semáforo sólo puede ser utilizado por el proceso que lo creó. //El 1 indica que sólo un proceso puede acceder al recurso que hay asociado //al semaforo. Resulfinal=0; //Inicializo de la variable global a cero.
//Inicializo los atributos de las distintas hebras.
for(n=0;n<numhebras;n++) {
pthread_attr_init(&(hebra[n].atributos));
}
//Ahora vamos a crear las hebras.
for (n=0;n<numhebras;n++) {
pthread_create(&(hebra[n].identif),&(hebra[n].atributos),&hebraMultiplicadora,(void *)&(hebra[n]));
}
//Con este bucle y mediante la función pthread_join() el thread (o hebra) que invoca a dicha funcion espera //a que acabe otro thread determinado.
for (n=0;n<numhebras;n++)
{
pthread_join((hebra[n].identif),(void **)&(hebra[n].reshebra));
}
//Imprimo por pantalla el resultado que devuelve cada hebra correspondiente a un elemento de la matriz resultado.
for (n=0;n<numhebras;n++) {
printf("\nPRINCIPAL: La hebra %d ha obtenido R(%d,%d)= %d\n",(hebra[n].numident),(hebra[n].fila),(hebra[n].columna),(hebra[n].reshebra));
}
printf("\n***********************************************\n"); printf("\nLas matrices que hemos multiplicado son las siguientes: \n"); printf("\n");
//Saco por pantalla la Matriz 1.
printf("Matriz 1:\n"); printf("\n");
for (i=0;i<tmatriz;i++) { for (j=0;j<tmatriz;j++) {
printf("%d ",matr1[i][j]);
}
printf("\n");
}
printf("\n");
printf("\n");
//Saco por pantalla la Matriz 2. printf("Matriz 2:\n"); printf("\n");
for (i=0;i<tmatriz;i++) { for (j=0;j<tmatriz;j++)
{
printf("%d ",matr2[i][j]);
}
printf("\n");
}
printf("\n"); //Saco por pantalla la Matriz resultado. printf("\nLa Matriz resultado queda así: \n"); printf("\n");
for (n=0;n<numhebras;n++) {
i=hebra[n].fila; j=hebra[n].columna; matresult[i][j]=hebra[n].reshebra;
}
for (i=0;i<tmatriz;i++) { for (j=0;j<tmatriz;j++)
{ printf("%d ",matresult[i][j]);
}
printf("\n");
} printf("\n***********************************************\n");
//Imprimo también por pantalla el resultado final de sumar los valores de la matriz resultado. printf("\nPRINCIPAL: Fin del programa con resultado = %d\n",Resulfinal);
printf("\n***********************************************\n");
printf("\n"); printf("\n");
//Libero los recursos de memoria que había reservado antes. for (n=0;n<tmatriz;n++) { for (i=0;i<tmatriz;i++) {
free(hebra[n].matr1[i]); free(hebra[n].matr2[i]);
}
free(hebra[n].matr1); free(hebra[n].matr2);
} }//Fin del Programa Principal
*****************************************
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h>
int Resulfinal;//Declaro la variable donde se almacenará el resultado total de sumar los elementos de la matriz resultado sem_t semaforo;//Declaro la variable que actuará como semáforo.
//Defino la estructura de una hebra.
struct hebestandar { pthread_t identif;//Identificador de la hebra. pthread_attr_t atributos;//Atributos de la hebra. int fila;//Entero que indica la fila a multiplicar. int columna;//Indica la columna a multiplicar. int **matr1; //Punteros a las matrices int **matr2;// int reshebra; //Este es el resultado que cada hebra almacenará. int numident; //Con este entero indicamos de qué hebra se trata si es la 0, la 1, la 2.... int xtam; //Contiene el tamaño de la matriz.
};
//Llamadas a las funciones.
int Multiplicar(int fila,int columna,int tmatriz,int **matr1,int **matr2); void * hebraMultiplicadora(void *p);
*******************************************************************
#include "libreria.h"
//Creo primero la función Multiplicar porque después tendrá que ser llamada desde la función hebraMultiplicadora.
//************************************************************************************************************** int Multiplicar(int fila,int columna,int tmatriz,int **matr1,int **matr2) { int i; int res=0; int resulparcial=0;
for (i=0;i<tmatriz;i++) { //Multiplico las componentes de la fila y de la columna que correspondan según el proceso //acumulando los resultados parciales hasta completar la fila y la columna. res=(matr1[fila][i])*(matr2[i][columna]); resulparcial=resulparcial+res; } return resulparcial;
}
//**************************************************************************************************************
void * hebraMultiplicadora(void *p)
{
int r=0; struct hebestandar *esthebra; esthebra=(struct hebestandar *)p; printf("\nLa hebra %d con identificador %ld calculado R(%d,%d)\n",(esthebra->numident),pthread_self(),(esthebra->fila),(esthebra->columna)); //Llamada a la función Multiplicar para ir obteniendo los elementos de la matriz resultado. r=Multiplicar(esthebra->fila,esthebra->columna,esthebra->xtam,esthebra->matr1,esthebra->matr2); //Mediante el uso de un semáforo voy a controlar el acceso a la variable del resultado final.
sem_wait(&semaforo); //Se mantiene en espera al proceso si están ocupados todos los recursos (semaforo=0). Resulfinal=Resulfinal+r; //Accedemos a la variable y le sumamos los resultados antes obtenidos. sem_post(&semaforo);//Con esta función hacemos que un recurso esté disponible cuando un proceso termina //de utilizarlo y entonces dicho recurso puede ser utilizado por otro proceso.
pthread_exit((void *)r); //Fin del proceso o hebra.
}
***********************************************************
EXE=multiplicaMat
OBJ=multiplicaMat.o
SOU=multiplicaMat.c
LIB=libreria.o
$(EXE):$(OBJ) libreria.o
gcc $(OBJ) $(LIB) -lpthread -o $(EXE)
$(OBJ):$(SOU)
gcc -c $(SOU) -o $(OBJ)
libreria.o:libreria.c
gcc -c libreria.c -o libreria.o
*********************************************************
C = gcc
CFLAGS = -Wall -g
SOURCE = ejecutaOrdenes.c
OBJECT = ejecutaOrdenes.o
EXEC = ejecutaOrdenes
$(EXEC): $(OBJECT)
$(CC) $(OBJECT) -o $(EXEC)
$(OBJECT): $(SOURCE)
$(CC) -c $(SOURCE) -o $(OBJECT)
***************************************************
EXE=info
OBJ=info.o
SOU=info.c
$(EXE):$(OBJ)
gcc $(OBJ) -o $(EXE)
$(OBJ):$(SOU)
gcc -c $(SOU) -o $(OBJ)
|