Está en la página 1de 48

INSTITUTO POLITECNICO

NACIONAL
ESCUELA SUPERIOR DE CMPUTO

LABORATORIO DE SISTEMAS
OPERATIVOS
PRCTICA 6:
Comunicacin inter procesos (IPC) en
Linux y Windows
INTEGRANTES:
Aguirre Cruz Eder Jonathan
Buenda Moreno Hugo Vidal
Saules Cortes Jhonatan
MATERIA: Sistemas Operativos
PROFESOR: Cortes Galicia Jorge
GRUPO: 2CM4
FECHA DE ENTREGA: 15 07- 2015

Competencia
El alumno comprende el funcionamiento de las tuberas (pipes) sin nombre y de la
memoria compartida como mecanismos de comunicacin entre procesos utilizando
el intercambio de mensajes tanto en el sistema operativo Linux como Windows.

Desarrollo
Observaciones Individuales
1.- Aguirre Cruz Eder Jonathan
Seccin Linux
1. A travs de la ayuda en lnea que proporciona Linux, investigue el
funcionamiento de la funcin: pipe(),shmget(), shmat(). Explique
los argumentos y retorno de la funcin.

shmget()
La sintaxis de la llamada de sistema shmget() es la siguiente:
shmid = shmget(llave, tamao, bandera);
donde el tamao especifica el nmero de bytes en la regin. El kernel del
sistema operativo busca la llave en la tabla de memoria compartida: si no la
encuentra y la bandera es IPC_CREAT, se crea una nueva regin y regresa
un identificador de tipo entero; si la encuentra, regresa el identificador
correspondiente a la regin de memoria.

shmat()
Un proceso anexa una regin de memoria compartida a su espacio de
direcciones virtuales con la llamada de sistema shmat().
virtaddr = shmat(id, addr, banderas);
id es el identificador de regin de memoria regresado por una llamada anterior
a shmget(), addr es la direccin virtual en donde el usuario desea anexar la
regin de memoria compartida, y banderas especifica las caractersticas de la
regin de memoria. Al ejecutar shmat(), el kernel verifica que el proceso tenga

los permisos necesarios para acceder a la regin. Examina la direccin


provista por el usuario: si es 0, el kernel determina una direccin virtual
conveniente. La memoria compartida no debe traslaparse con las regiones del
espacio de direcciones virtuales. El valor virtaddr regresado por esta llamada
es la direccin en la que el kernel anex la memoria compartida, no
necesariamente la direccin addr especificada por el usuario. virtaddr es un
apuntador genrico (a ningn tipo de dato en especial, implementado en C
comnmente como un apuntador de tipo char), es decir:
char *virtaddr;
Para desasociar la regin de memoria virtual del espacio de direcciones
virtuales, se utiliza la llamada shmdt() como sigue:
shmdt(virtaddr)

2.- Saules Cortes Jhonatan


2. Capture, compile y ejecute el siguiente programa. Observe su funcionamiento
y explique.
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#define VALOR 1
int main (void)
{
int desc_arch[2];
char bufer[100];
if(pipe(desc_arch)!=0)
exit(1);
if(fork()==0)
{
while(VALOR)
{
read(desc_arch[0],bufer,sizeof(bufer));
printf(Se recibi: %s\n, bufer);
}
}
while(VALOR)
{
gets(bufer);
write(desc_arch[1],bufer,strlen(bufer)+1);
}
}

Pantalla de ejecucin

3.- Buendia Moreno Hugo Vidal


3. Capture, compile y ejecute los siguientes programas. Observe su
funcionamiento
y
explique.
Ejecute
de
la
siguiente
forma:
C:\>nombre_programa_padre_hijo
#include <windows.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char mensaje[]=Tuberias en Windows;
DWORD escritos;
HANDLE hLecturaPipe,hEscrituraPipe;
PROCESS_INFORMATION piHijo;
STARTUPINFO siHijo;
SECURITY_ATTRIBUTES pipeSeg = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
/*Obtencin de informacin para la inicializacin del proceso hijo*/
GetStartupInfo(&siHijo);
/*Creacin de la tubera sin nombre*/
CreatePipe(&hLecturaPipe, &hEscrituraPipe, &pipeSeg,0);
/*Escritura en la tubera sin nombre*/
WriteFile(hEscrituraPipe, mensaje, strlen(mensaje)+1, &escritos, NULL);

siHijo.hStdInput = hLecturaPipe;
siHijo.hStdError = GetStdHandle (STD_ERROR_HANDLE);
siHijo.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
siHijo.dwFlags = STARTF_USESTDHANDLES;
CreateProcess(NULL,argv[1],NULL,NULL,TRUE, /*Hereda el proceso hijo los
manejadores de la tubera del padre*/ 0,NULL,NULL,&siHijo,&piHijo);
WaitForSingleObject(piHijo.hProcess,INFINITE);
printf(Mensaje recibido en el proceso hijo, termina el proceso padre\n);
CloseHandle(hLecturaPipe);
CloseHandle(hEscrituraPipe);
CloseHandle(piHijo.hThread);
CloseHandle(piHijo.hProcess);
return 0;
}
/*Programa hijo.c*/
#include <windows.h>
#include <stdio.h>
int main()
{
char mensaje[20];
DWORD leidos;
HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
SECURITY_ATTRIBUTES pipeSeg = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
/*Lectura desde la tubera sin nombre*/
ReadFile(hStdIn, mensaje, sizeof(mensaje), &leidos, NULL);
printf(Mensaje recibido del proceso padre: %s\n, mensaje);
CloseHandle(hStdIn);
printf(Termina el proceso hijo, continua el proceso padre\n);
return 0;
}

Pantalla de ejecucin

2.- Saules Cortes Jhonatan

4. Programe una aplicacin que cree un proceso hijo a partir de un proceso


padre, el proceso padre enviar al proceso hijo, a travs de una tubera, dos
matrices de 15 x 15 a multiplicar por parte del hijo, mientras tanto el proceso
hijo crear un hijo de l, al cual enviar dos matrices de 15 x 15 a sumar en el
proceso hijo creado, nuevamente el envo de estos valores ser a travs de
una tubera. Una vez calculado el resultado de la suma, el proceso hijo del
hijo devolver la matriz resultante a su abuelo (va tubera). A su vez, el
proceso hijo devolver la matriz resultante de la multiplicacin que realiz a
su padre. Finalmente, el proceso padre obtendr la matriz inversa de cada
una de las matrices recibidas y el resultado lo guardar en un archivo para
cada matriz inversa obtenida. Programe esta aplicacin tanto para Linux
como para Windows utilizando las tuberas de cada sistema operativo.

Seccin Linux
/*Padre.c*/
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
void SumaMatrices(int a[][15],int b[]
[15],int r[][15]);
void RestaMatrices(int a[][15],int b[]
[15],int r[][15]);
void MultiplicaMatrices(int a[][15],int
b[][15],int r[][15]);
void TraspuestaMatriz(int a[][15]);
int InversaMatriz(int a[][15], float
matrizDeInversa[][15]);
void ArchPutsMatriz(FILE *Archivo, int
Matriz[][15]);
void ArchPutsMatrizFloat(FILE *Archivo,
float Matriz[][15]);
void ArchImprimeMatriz(FILE *Archivo);
void ArchImprimeContenido(FILE
*Archivo);
int main(int argc, char* argv[]){
//Definiendo las matrices a trabajar
int Matriz1[15][15],Matriz2[15][15];
int MatrizResultado[15][15];
int i,j;
FILE
*ArchMatriz1=fopen("mat1.txt","r");
FILE

*ArchMatriz2=fopen("mat2.txt","r");
if (ArchMatriz1==NULL ||
ArchMatriz2==NULL){
printf("Error al cargar los
archivos\n");
exit(0);
}
//Obtener de los archivos las matrices
for(i=0; i<15; i++){
for(j=0; j<15; j++){
fscanf(ArchMatriz1,"%d",&Matriz1[i]
[j]);
fscanf(ArchMatriz2,"%d",&Matriz2[i]
[j]);
}
}
fclose(ArchMatriz1);
fclose(ArchMatriz2);
//Creando la tuberia
int tuberiaFD[2];
if(pipe(tuberiaFD)!=0)
return 0;
//Agregando valores enteros a carcteres
para los descriptores de la tuberia
char tuberiaFD_read[15];
sprintf(tuberiaFD_read, "%d",
tuberiaFD[0]);
char tuberiaFD_write[15];
sprintf(tuberiaFD_write, "%d",
tuberiaFD[1]);
//Parametros para el hijo

char* argHijo[15];
argHijo[0]="Hijo";
argHijo[1]=tuberiaFD_read;
argHijo[2]=tuberiaFD_write;
argHijo[3]=NULL;
//Creacion del proceso
pid_t pid=fork();
int status;
if(pid == -1)
printf("Error al crear el proceso
\n");
else if(pid == 0)
execv(argHijo[0],argHijo);
else{
write(tuberiaFD[1],Matriz1,sizeof(Matriz
1));
write(tuberiaFD[1],Matriz2,sizeof(Matriz
2));
waitpid(pid,&status,0);
//Recuperando matrices devueltas por
la familia
int MatrizSumaResultado[15][15];
int MatrizMultResultado[15][15];
read(tuberiaFD[0],MatrizSumaResultado,
sizeof(MatrizSumaResultado));
read(tuberiaFD[0],MatrizMultResultado,s
izeof(MatrizMultResultado));
//Sacando sus inversas....
float InvMatrizSumaResultado[15]
[15];
float InvMatrizMultResultado[15][15];
FILE
*MatrizInversaPorHijo=fopen("MatrizInv
ersaPorHijo","w");
FILE
*MatrizInversaPorNieto=fopen("MatrizIn
versaPorNieto","w");
if(InversaMatriz(MatrizSumaResultado,
InvMatrizSumaResultado)==1)
ArchPutsMatrizFloat(MatrizInversaPorHijo
,InvMatrizSumaResultado);
else
fprintf(MatrizInversaPorHijo,"No

tiene inversa");
if(InversaMatriz(MatrizMultResultado,
InvMatrizMultResultado)==1)
ArchPutsMatrizFloat(MatrizInversaPorNiet
o,InvMatrizMultResultado);
else
fprintf(MatrizInversaPorNieto,"No
tiene inversa");
return 0;
}
return 0;
}
void MultiplicaMatrices(int a[][15],int
b[][15],int r[][15]){
int i,j,k;
for(i=0;i<15;i++){
for (j=0;j<15;j++){
r[i][j]=0;
for(k=0;k<15;k++){
r[i][j]+= a[i][k] * b[k][j];
}
}
}
}
int InversaMatriz(int a[][15], float
matrizDeInversa[][15]){
int i, j, k , terminosIguales=0,
orden=15;
float pivote=0,
matrizDeIdentidad[orden][orden],
dividendo=0;
//Inicializando matriz identidad
for(i=0;i<orden;i++){
for(j=0;j<orden;j++){
if(i==j){
matrizDeInversa[i][j]=1;
}
else{
matrizDeInversa[i][j]=0;
}
}
}
//Copiar matriz recibida entera en la
flotante
for(i=0;i<orden;i++){
for(j=0;j<orden;j++){
matrizDeIdentidad[i][j]=(float)a[i]

[j];
}
}
//Iniciar el algoritmo de obtener la
inversa por Gauss Jordan
//Volviendola triangular inferior
for(i=0;i<orden;i++){
pivote=matrizDeIdentidad[i][i];
for(j=i;j<orden-1;j++){
dividendo= matrizDeIdentidad[j+1]
[i];
terminosIguales=0;
for(k=0;k<orden;k++){
if(matrizDeIdentidad[j+1]
[k]==matrizDeIdentidad[i][k]){
terminosIguales++;
if(terminosIguales==orden){
return 0;
}
}
matrizDeIdentidad[j+1][k]=(
(pivote/dividendo) *
matrizDeIdentidad[j+1][k] )matrizDeIdentidad[i][k];
matrizDeInversa[j+1][k]=(
(pivote/dividendo) *
matrizDeInversa[j+1][k] )matrizDeInversa[i][k];
}
}
}
//Volviendola triangular superior y asi
volverla una matriz escalar (o puede que
ya de identidad)
for(i=orden-1;0<=i;i--){
pivote=matrizDeIdentidad[i][i];
for(j=i;0<j;j--){
dividendo= matrizDeIdentidad[j-1]
[i];
for(k=orden-1;0<=k;k--){
matrizDeIdentidad[j-1][k]=(
(dividendo/pivote) *
matrizDeIdentidad[i][k] )matrizDeIdentidad[j-1][k];
matrizDeInversa[j-1][k]=(
(dividendo/pivote) * matrizDeInversa[i]
[k] )- matrizDeInversa[j-1][k];
}
}
}

//Finalmente, la matriz inversa la


volvemos identidad dividiendola si es
escalar
for(i=0;i<orden;i++){
for(j=0;j<orden;j++){
matrizDeInversa[i]
[j]=matrizDeInversa[i]
[j]/matrizDeIdentidad[i][i];
}
}
return 1;
}
void ArchPutsMatriz(FILE *Archivo, int
Matriz[][15]){
int i,j;
for (i=0;i<15;i++){
for(j=0;j<15;j++){
fprintf(Archivo,"%d ",Matriz [i][j]);
}
fprintf(Archivo,"\n");
}
}
void ArchPutsMatrizFloat(FILE *Archivo,
float Matriz[][15]){
int i,j;
for (i=0;i<15;i++){
for(j=0;j<15;j++){
fprintf(Archivo,"%f ",Matriz [i][j]);
}
fprintf(Archivo,"\n");
}
}
void ArchImprimeMatriz(FILE *Archivo){
int i,j,a[15][15];
for(i=0; i<15; i++){
for(j=0; j<15; j++){
fscanf(Archivo,"%d",&a[i][j]);
printf("%d ",a[i][j]);
}
printf("\n");
}
}
void ArchImprimeContenido(FILE
*Archivo){
char Caracter;

while(!feof(Archivo)){
fscanf(Archivo,"%c",&Caracter);
printf("%c",Caracter);

}
printf("\n");
}

/*Hijo.c*/
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/wait.h>
void SumaMatrices(int a[][15],int b[]
[15],int r[][15]);
void ArchPutsMatriz(FILE *Archivo, int
Matriz[][15]);
void ArchPutsMatrizFloat(FILE *Archivo,
float Matriz[][15]);
void ArchImprimeMatriz(FILE *Archivo);
void ArchImprimeContenido(FILE
*Archivo);
int main(int argc, char* argv[]){
//Recuperando valores de tuberia
int tuberiaFD[2];
int i,j;
tuberiaFD[0]=atoi( argv[1] );
tuberiaFD[1]=atoi( argv[2] );
//Recuperando la matriz de la tuberia
int Matriz1[15][15];
int Matriz2[15][15];
int Matriz3[15][15];
int Matriz4[15][15];
//Leyendo las matrics a traves de la
tuberia
read(tuberiaFD[0],Matriz1,sizeof(Matriz
1));
read(tuberiaFD[0],Matriz2,sizeof(Matriz
2));
//Realizando Operaciones
int MatrizSumaResultado[15][15];
SumaMatrices(Matriz1,Matriz2,MatrizSu
maResultado);

//Definiendo la matriz a operar


FILE
*ArchMatriz3=fopen("mat3.txt","r");
FILE
*ArchMatriz4=fopen("mat4.txt","r");
if (ArchMatriz3==NULL ||
ArchMatriz4==NULL){
printf("Error al cargar los
archivos\n");
exit(0);
}
//Obtener de los archivos las matrices
for(i=0; i<15; i++){
for(j=0; j<15; j++){
fscanf(ArchMatriz3,"%d",&Matriz3[i]
[j]);
fscanf(ArchMatriz4,"%d",&Matriz4[i]
[j]);
}
}
fclose(ArchMatriz3);
fclose(ArchMatriz4);
//Parametros para el hijo
char* argNieto[10];
argNieto[0]="Nieto";
argNieto[1]=argv[1];
argNieto[2]=argv[2];
argNieto[3]=NULL;
//Creacion del proceso
pid_t pid=fork();
int status;
if(pid == -1)
printf("Error al crear el proceso
\n");
else if(pid == 0)
execv(argNieto[0],argNieto);
else{
write(tuberiaFD[1],Matriz3,sizeof(Matriz

3));
write(tuberiaFD[1],Matriz4,sizeof(Matriz
4));
write(tuberiaFD[1],MatrizSumaResultado
,sizeof(MatrizSumaResultado));
waitpid(pid,&status,0);
}
return 0;
}
void SumaMatrices(int a[][15],int b[]
[15],int r[][15]){
int i,j;
for (i=0;i<15;i++){
for(j=0;j<15;j++){
r[i][j]=a[i][j] + b[i][j];
}
}
}
void ArchPutsMatriz(FILE *Archivo, int
Matriz[][15]){
int i,j;
for (i=0;i<15;i++){
for(j=0;j<15;j++){
fprintf(Archivo,"%d ",Matriz [i][j]);
}
fprintf(Archivo,"\n");
}
}

void ArchPutsMatrizFloat(FILE *Archivo,


float Matriz[][15]){
int i,j;
for (i=0;i<15;i++){
for(j=0;j<15;j++){
fprintf(Archivo,"%f ",Matriz [i][j]);
}
fprintf(Archivo,"\n");
}
}
void ArchImprimeMatriz(FILE *Archivo){
int i,j,a[15][15];
for(i=0; i<15; i++){
for(j=0; j<15; j++){
fscanf(Archivo,"%d",&a[i][j]);
printf("%d ",a[i][j]);
}
printf("\n");
}
}
void ArchImprimeContenido(FILE
*Archivo){
char Caracter;
while(!feof(Archivo)){
fscanf(Archivo,"%c",&Caracter);
printf("%c",Caracter);
}
printf("\n");
}

/*Nieto.c*/
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/wait.h>
void ArchPutsMatriz(FILE *Archivo, int
Matriz[][15]);
void MultiplicaMatrices(int a[][15],int
b[][15],int r[][15]);
int main(int argc, char* argv[]){
//Recuperando valores de tuberia
int tuberiaFD[2];

tuberiaFD[0]=atoi( argv[1] );
tuberiaFD[1]=atoi( argv[2] );
//Recuperando la matriz de la tuberia
int Matriz3[15][15];
int Matriz4[15][15];
//Leyendo las matrics a traves de la
tuberia
read(tuberiaFD[0],Matriz3,sizeof(Matriz
3));
read(tuberiaFD[0],Matriz4,sizeof(Matriz
4));

//Realizando Operaciones
int MatrizMultResultado[15][15];
FILE
*MatrizMulti=fopen("MatrizMulti","w");
MultiplicaMatrices(Matriz3,Matriz4,Matriz
MultResultado);
write(tuberiaFD[1],MatrizMultResultado,
sizeof(MatrizMultResultado));
ArchPutsMatriz(MatrizMulti,MatrizMultRes
ultado);
return 0;
}
void MultiplicaMatrices(int a[][15],int
b[][15],int r[][15]){
int i,j,k;

for(i=0;i<15;i++){
for (j=0;j<15;j++){
r[i][j]=0;
for(k=0;k<15;k++){
r[i][j]+= a[i][k] * b[k][j];
}
}
}
}
void ArchPutsMatriz(FILE *Archivo, int
Matriz[][15]){
int i,j;
for (i=0;i<15;i++){
for(j=0;j<15;j++){
fprintf(Archivo,"%d ",Matriz [i][j]);
}
fprintf(Archivo,"\n");
}
}

Pantalla de ejecucin

1.- Aguirre Cruz Eder Jonathan


Seccin Windows
Cdigo fuente
#include <stdlib.h>
#include <windows.h>

CreateProcess(NULL,
argv[1],
NULL, NULL, TRUE, 0, NULL, NULL,
&siHijo, &piHijo);

int main(int argc, char *argv[]){


HANDLE hLecturaPipe;
PROCESS_INFORMATION piHijo;
STARTUPINFO siHijo;

WaitForSingleObject(piHijo.hProcess,INFI
NITE);
CloseHandle(piHijo.hThread);
CloseHandle(piHijo.hProcess);

GetStartupInfo(&siHijo);
siHijo.hStdInput = hLecturaPipe;
siHijo.hStdError
=
GetStdHandle(STD_ERROR_HANDLE);
siHijo.hStdOutput
=
GetStdHandle(STD_OUTPUT_HANDLE);
siHijo.dwFlags
=
STARTF_USESTDHANDLES;

system("PAUSE>nul");
return 0;
}

/*Padre.c*/
#include <windows.h>
#include <stdio.h>
#define TAM_MATRIZ 15
int determinanteRecursivo(int **M, int
tam);
void
calcularCofactores(int
**M,int
**M_cofactores, int tam);
void llenarMatrices(int M1[TAM_MATRIZ]
[TAM_MATRIZ], int M2[TAM_MATRIZ]
[TAM_MATRIZ]);
typedef struct Informacion info;
struct Informacion{
int M1[TAM_MATRIZ][TAM_MATRIZ];
int M2[TAM_MATRIZ][TAM_MATRIZ];
HANDLE escritura;
};
int main(int argc, char *argv[]){
argc = 2;
argv[1] = "Hijo.exe";
info argumentos;
int i, j, det;
int multiplicacion[TAM_MATRIZ]
[TAM_MATRIZ];
int suma[TAM_MATRIZ][TAM_MATRIZ];
int **M_inversa1 = NULL;
int **M_inversa2 = NULL;
int **M_cofactores = NULL;
FILE *archivo;
DWORD escritos, leidos, leidos2;
HANDLE
hLecturaPipe,
hEscrituraPipe, nmulti, hEscrituraPipe2,
hLecturaPipe2,
hEscrituraPipe3,
hLecturaPipe3;
PROCESS_INFORMATION piHijo;
STARTUPINFO siHijo;
SECURITY_ATTRIBUTES pipeSeg
=
{sizeof(SECURITY_ATTRIBUTES),NULL,T
RUE};

llenarMatrices(argumentos.M1,argumen
tos.M2);

printf("Matriz 1 para multiplicacin");


for(i = 0; i < TAM_MATRIZ; i++)
{
printf("\n");
for(j = 0; j < TAM_MATRIZ;
j++)
printf("%d ",
argumentos.M1[i][j]);
}
printf("\n\n");
printf("Matriz 2 para multiplicacion");
for(i = 0; i < TAM_MATRIZ; i++)
{
printf("\n");
for(j = 0; j < TAM_MATRIZ;
j++)
printf("%d ",
argumentos.M2[i][j]);
}
printf("\n\n");
GetStartupInfo(&siHijo);
CreatePipe(&hLecturaPipe,&hEscrituraPi
pe,&pipeSeg,0);
CreatePipe(&hLecturaPipe2,&hEscritura
Pipe2,&pipeSeg,0);
CreatePipe(&hLecturaPipe3,&hEscritura
Pipe3,&pipeSeg,0);
argumentos.escritura
=
hEscrituraPipe3;
WriteFile(hEscrituraPipe,
&argumentos,
sizeof(argumentos),
&escritos, NULL);
siHijo.hStdInput = hLecturaPipe;
siHijo.hStdError
=
GetStdHandle(STD_ERROR_HANDLE);
siHijo.hStdOutput
=
hEscrituraPipe2;

siHijo.dwFlags
STARTF_USESTDHANDLES;

CreateProcess(NULL,
argv[1],
NULL, NULL, TRUE, 0, NULL, NULL,
&siHijo, &piHijo);
ReadFile(hLecturaPipe2,&multiplicaci
on,sizeof(multiplicacion),&leidos,NULL);
printf("Matriz ya multiplicada");
for(i = 0; i < TAM_MATRIZ; i++)
{
printf("\n");
for(j = 0; j < TAM_MATRIZ;
j++)
printf("%d ",
multiplicacion[i][j]);
}

ReadFile(hLecturaPipe3,&suma,sizeof(su
ma),&leidos2,NULL);
printf("\n\n");
printf("Matriz ya sumada");
for(i = 0; i < TAM_MATRIZ; i++)
{
printf("\n");
for(j = 0; j < TAM_MATRIZ;
j++)
printf("%d ", suma[i]
[j]);
}
M_inversa1
=
(int
**)malloc(sizeof(int *) * TAM_MATRIZ);
M_inversa2
=
(int
**)malloc(sizeof(int *) * TAM_MATRIZ);
M_cofactores
=
(int
**)malloc(sizeof(int *) * TAM_MATRIZ);
for(i = 0; i < TAM_MATRIZ; i++)
{
M_inversa1[i]
=
(int
*)malloc(sizeof(int) * TAM_MATRIZ);
M_inversa2[i]
=
(int
*)malloc(sizeof(int) * TAM_MATRIZ);

M_cofactores[i]
=
(int
*)malloc(sizeof(int) * TAM_MATRIZ);
}
for(i = 0; i < TAM_MATRIZ; i++)
for(j = 0; j < TAM_MATRIZ;
j++)
{
M_inversa1[i][j] =
multiplicacion[i][j];
M_inversa2[i][j] =
suma[i][j];
}
det
=
determinanteRecursivo(M_inversa1,
TAM_MATRIZ);
if(det == 0) //Si la matriz 1 no
tiene inversa.
{
for(i = 0; i < TAM_MATRIZ;
i++)
for(j = 0; j <
TAM_MATRIZ; j++)
M_inversa1[i][j] = 0;
}
else
{
calcularCofactores(M_inversa1,
M_cofactores, TAM_MATRIZ);
for(i = 0; i < TAM_MATRIZ;
i++)
for(j = 0; j <
TAM_MATRIZ; j++)
{
M_inversa1[i][j]
M_cofactores[j][i];

M_inversa1[i][j] /= det;
}
}
det
=
determinanteRecursivo(M_inversa2,
TAM_MATRIZ);
if(det == 0) //Si la matriz 2 no
tiene inversa.

for(i = 0; i < TAM_MATRIZ; i++)


{
free(M_inversa1[i]);
free(M_inversa2[i]);
free(M_cofactores[i]);
}
free(M_inversa1);
free(M_inversa2);
free(M_cofactores);

for(i = 0; i < TAM_MATRIZ;


i++)
for(j

0;

<

TAM_MATRIZ; j++)
M_inversa2[i][j] = 0;
}
else
{

printf("\n\nI've done my work");


calcularCofactores(M_inversa2,
M_cofactores, TAM_MATRIZ);
for(i = 0; i < TAM_MATRIZ;
i++)
for(j = 0; j <
TAM_MATRIZ; j++)
{
M_inversa2[i][j]
M_cofactores[j][i];

M_inversa2[i][j] /= det;
}
}
archivo
fopen("inversa1.txt","w+");

for(i = 0; i < TAM_MATRIZ; i++)


{
fprintf(archivo,"\n");
for(j = 0; j < TAM_MATRIZ; j++)
fprintf(archivo,"%d
", M_inversa1[i][j]);
}
fclose(archivo);
archivo = fopen("inversa2.txt","w+");
for(i = 0; i < TAM_MATRIZ; i++)
{
fprintf(archivo,"\n");
for(j = 0; j < TAM_MATRIZ; j++)
fprintf(archivo,"%d
", M_inversa2[i][j]);
}

CloseHandle(hLecturaPipe);
CloseHandle(hEscrituraPipe);
CloseHandle(piHijo.hThread);
CloseHandle(piHijo.hProcess);
}
void llenarMatrices(int M1[TAM_MATRIZ]
[TAM_MATRIZ],
int M2[TAM_MATRIZ]
[TAM_MATRIZ])
{
int x, y;
srand(time(NULL));
for(x = 0; x < TAM_MATRIZ; x+
+)
for(y
=
0;
y
<
TAM_MATRIZ; y++)
M1[x][y] = rand()
% 21;
for(x = 0; x < TAM_MATRIZ; x+
+)
for(y
TAM_MATRIZ; y++)

0;

<

M2[x][y] = rand()
% 21;
}
int determinanteRecursivo(int **M, int
tam)
{
int **M_aux = NULL;
int det = 0, i, j, k, a;
M_aux = (int **)malloc(sizeof(int
*) * (tam - 1));

for(i = 0; i < (tam - 1); i++)


M_aux[i]
=
*)malloc(sizeof(int) * (tam - 1));

int **M_aux;
(int

//Caso base.
if(tam == 2)
{
for(i = 0; i < (tam - 1); i+

M_aux = (int **)malloc(sizeof(int


*) * (tam - 1));
for(i = 0; i < tam - 1; i++)
M_aux[i]
=
(int
*)malloc(sizeof(int) * (tam - 1));

+)
free(M_aux[i]);
free(M_aux);
return M[0][0] * M[1][1] M[0][1] * M[1][0];
}
//Parte recursiva.
for(i = 0; i < tam; i++)
{
for(j = 1; j < tam; j++)
{
a = 0;
for(k = 0; k < tam;
k++)
if(k != i)

for(i = 0; i < tam; i++)


{
for(j = 0; j < tam; j++)
{
a = 0;
for(k = 0; k < tam;
k++)
{
if(k != i)
{
b

0;
for(l
= 0; l < tam; l++)
if(l != j)

M_aux[j - 1][a++] = M[j][k];


}
det
+=
M[0][i]
*
(int)pow(-1.0,
(2
+
i))
*
determinanteRecursivo(M_aux, tam - 1);
}
for(i = 0; i < (tam - 1); i++)
free(M_aux[i]);
free(M_aux);
return det;

M_aux[a][b++] = M[k][l];
a++;
}
}
det
=
determinanteRecursivo(M_aux, tam - 1);
M_cofactores[i][j]
= det * (int)pow(-1.0, (i + j + 2));
}
}

}
void calcularCofactores(int **M,
**M_cofactores, int tam)
{
int i, j, k, l, a, b, det = 0;

for(i = 0; i < tam - 1; i++)


free(M_aux[i]);
free(M_aux);

int
}

/*Hijo.c*/
#include <windows.h>

#include <stdio.h>

#define TAM_MATRIZ 15
void llenarMatrices(int M1[TAM_MATRIZ]
[TAM_MATRIZ], int M2[TAM_MATRIZ]
[TAM_MATRIZ]);
typedef struct Informacion info;
struct Informacion{
int M1[TAM_MATRIZ][TAM_MATRIZ];
int M2[TAM_MATRIZ][TAM_MATRIZ];
HANDLE nieto;
};
int main(int argc, char *argv[]){
argc = 2;
argv[1] = "Nieto.exe";
info recibido;
info argumentos;
int multiplicacion[TAM_MATRIZ]
[TAM_MATRIZ];
int i, j;
HANDLE
hLecturaPipe,
hEscrituraPipe;
HANDLE stdOut;
PROCESS_INFORMATION piHijo;
STARTUPINFO siHijo;
DWORD leidos, escritos;
HANDLE
hStdIn
=
GetStdHandle(STD_INPUT_HANDLE);
HANDLE
hStdOut
=
GetStdHandle(STD_OUTPUT_HANDLE);
SECURITY_ATTRIBUTES pipeSeg =
{sizeof(SECURITY_ATTRIBUTES), NULL,
TRUE};
ReadFile(hStdIn,&recibido,sizeof(recib
ido),&leidos,NULL);
stdOut = recibido.nieto;
for(i = 0; i < TAM_MATRIZ; i++)
{
for(j = 0; j < TAM_MATRIZ;
j++)
{

multiplicacion[i][j] =
recibido.M1[i][j] * recibido.M2[i][j];
}
}
llenarMatrices(argumentos.M1,argum
entos.M2);
WriteFile(hStdOut, &multiplicacion,
sizeof(multiplicacion), &escritos, NULL);
GetStartupInfo(&siHijo);
CreatePipe(&hLecturaPipe,&hEscrituraPi
pe,&pipeSeg,0);
WriteFile(hEscrituraPipe,
&argumentos,
sizeof(argumentos),
&escritos, NULL);
siHijo.hStdInput = hLecturaPipe;
siHijo.hStdError
=
GetStdHandle(STD_ERROR_HANDLE);
siHijo.hStdOutput = stdOut;
siHijo.dwFlags
=
STARTF_USESTDHANDLES;
CreateProcess(NULL,
argv[1],
NULL, NULL, TRUE, 0, NULL, NULL,
&siHijo, &piHijo);
WaitForSingleObject(piHijo.hProcess,INFI
NITE);
CloseHandle(hStdIn);
CloseHandle(hLecturaPipe);
CloseHandle(hEscrituraPipe);
CloseHandle(piHijo.hThread);
CloseHandle(piHijo.hProcess);
}
void llenarMatrices(int M1[TAM_MATRIZ]
[TAM_MATRIZ],
int M2[TAM_MATRIZ]
[TAM_MATRIZ])
{
int x, y;
srand(time(NULL));
for(x = 0; x < TAM_MATRIZ; x+
+)

for(y
TAM_MATRIZ; y++)

0;

<

for(x = 0; x < TAM_MATRIZ; x+


+)

M1[x][y] = rand()
% 25;

for(y
TAM_MATRIZ; y++)

0;

<

M2[x][y] = rand()
% 25;
}

/*Nieto.c*/
#include <windows.h>
#include <stdio.h>
#define TAM_MATRIZ 15

SECURITY_ATTRIBUTES pipeSeg =
{sizeof(SECURITY_ATTRIBUTES), NULL,
TRUE};

typedef struct Informacion info;


struct Informacion{

ReadFile(hStdIn,&recibido,sizeof(recib
ido),&leidos,NULL);

int M1[TAM_MATRIZ][TAM_MATRIZ];
int M2[TAM_MATRIZ][TAM_MATRIZ];
HANDLE padre;
};

for(i = 0; i < TAM_MATRIZ; i++)


{
for(j = 0; j < TAM_MATRIZ;
j++)
{
suma[i][j] = recibido.M1[i][j] +
recibido.M2[i][j];
}
}

int main( ){
info recibido;
int suma[TAM_MATRIZ][TAM_MATRIZ];
int i, j;
HANDLE
hStdOut
=
GetStdHandle(STD_OUTPUT_HANDLE);
DWORD leidos, escritos;
HANDLE
hStdIn
=
GetStdHandle(STD_INPUT_HANDLE);

WriteFile(hStdOut,&suma,sizeof(suma
),&escritos,NULL);
CloseHandle(hStdIn);
}

Pantalla de ejecucin

2.- Saules Cortes Jhonatan


Seccin Linux
5. Capture, compile y ejecute los siguientes programas para Linux. Observe y
explique su funcionamiento.

#include <sys/types.h> /*Cliente de la memoria compartida*/


#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>

#define TAM_MEM 27 /*Tamao de la memoria compartida en bytes*/


int main()
{
int shmid;
key_t llave;
char *shm, *s;
llave = 5678;
if((shmid = shmget(llave,TAM_MEM,0666)) <0)(
perror(Error al obtener memoria compartida: shmget);
exit(-1);
}
if((shm = shmat(shmid,NULL,0)) == (char *)-1){
perror(Error al enlazar la memoria compartida: shmat);
exit(-1);
}
for(s = shm; *s!=\0;s++)
putchar(*s);
putchar(\n);
*shm = *;
exit(0);
}

#include <sys/types.h> /*Servidor de la memoria compartida*/

#include <sys/ipc.h> /*(ejecutar el servidor antes de ejecutar al cliente)*/


#include <sys/shm.h>
#include <stdio.h>
#define TAM_MEM 27 /*Tamao de la memoria compartida en bytes*/
int main()
{
int shmid;
key_t llave;
char *shm, *s;
llave = 5678;
if((shmid = shmget(llave,TAM_MEM,IPC_CREAT|0666))<0){
perror(Error al obtener memoria compartida: shmget);
exit(-1);
}
if((shm = shmat(shmat(shmid,NULL,0))==(char *)-1){
perror(Error al enlazar la memoria compartida: shmat);
exit(-1);
}
s = shm;
for(c = a; c<=z; c++)
*s++ = c;
*s = \0;
while(*shm!=*)

sleep (1);
exit(0);
}

Pantalla de ejecucin

1.- Aguirre Cruz Eder Jonathan


Seccin Windows
6. Capture, compile y ejecute los siguientes programas para Windows. Observe
y explique su funcionamiento.

#include <windows.h> /*Cliente de la memoria compartida*/


#include <stdio.h>
#define TAM_MEM 27 /*Tamao de la memoria compartida en bytes*/
int main (void)

{
HANDLE hArchMapeo;
char *idMemCompartida = Memoria Compartida;
char *apDatos, *apTrabajo, c;
if((hArchMapeo=OpenFileMapping(
FILE_MAP_ALL_ACCESS, //acceso lectura/escritura de la memoria compartida
FALSE, //no se hereda el nombre
idMemCompartida) //identificador de la memoria compartida
)==NULL) //
{
printf(No se abri archivo
(%i)\n,GetLastError());

de

mapeo

de

la

memoria

compartida:

exit(-1);
}
if((apDatos=(char *)MapViewOfFile(hArchMapeo, //Manejador del mapeo
FILE_MAP_ALL_ACCESS, //Permiso de lectura/escritura en la memoria
0,
0,
TAM_MEM))==NULL)
{
printf(No se accedi a la memoria compartida: (%i)\n,GetLastError());
CloseHandle(hArchMapeo);
exit(-1);
}

for(apTrabajo = apDatos; *apTrabajo != \0;apTrabajo++)


putchar(*apTrabajo);
putchar(\n);
*apDatos = *;
UnmapViewOfFile(apDatos);
CloseHandle(hArchMapeo);
exit(0);
}

#include <windows.h> /*Servidor de la memoria compatida*/


#include <stdio.h>
#define TAM_MEM 27 /*Tamao de la memoria compartida en bytes*/
int main (void)
{
HANDLE hArchMapeo;
char *idMemCompartida = Memoria Compartida;
char *apDatos, *apTrabajo, c;
if((hArchMapeo=CreateFileMapping(
INVALID_HANDLE_VALUE, //usa memoria compartida
NULL, //seguridad por default
PAGE_READWRITE, //acceso lectura/escritura a la memoria
0, //tamao mximo parte alta de un DWORD
TAM_MEM, //tamao mximo parte baja de un DWORD

idMemCompartida) //identificador de la memoria compartida


)==NULL)
{
printf(No se mapeo la memoria compartida: (%i)\n, GetLastError());
exit(-1);
}
if((apDatos=(char *)MapViewOfFile(hArchMapeo, //Manejador del mapeo
FILE_MAP_ALL_ACCESS, //Permiso de lectura/escritura en la memoria
0,
0,
TAM_MEM))==NULL)
{
printf(No se cre la memoria compartida: (%i)\n,GetLastError());
CloseHandle(hArchMapeo);
exit(-1);
}
apTrabajo = apDatos;
for(c=a;c<=z;c++)
*apTrabajo++=c;
*apTrabajo=\0;
while(*apDatos !=*)
sleep(1);
UnmapViewOfFile(apDatos);

CloseHandle(hArchMapeo);
exit(0);
}

2.- Saules Cortes Jhonatan


7. Programe nuevamente el problema del punto cuatro, utilizando en esta
ocasin memoria compartida en lugar de tuberas (utilice tantas memorias
compartidas como requiera). Programe esta aplicacin tanto para Linux como
para Windows utilizando la memoria compartida de cada sistema operativo.

Seccin Linux
/*padre.c*/
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#define MATRIXBYTES 400
/*
Orden de ejecucion:
1.- Padre
2.- Hijo
3.- Nieto
*/
void SumaMatrices(int a[][15],int b[]
[15],int r[][15]);
void RestaMatrices(int a[][15],int b[]
[15],int r[][15]);
void MultiplicaMatrices(int a[][15],int
b[][15],int r[][15]);
void TraspuestaMatriz(int a[][15]);
int InversaMatriz(int a[][15], float
matrizDeInversa[][15]);
void ArchPutsMatriz(FILE *Archivo, int
Matriz[][15]);

void ArchPutsMatrizFloat(FILE *Archivo,


float Matriz[][15]);
void ArchImprimeMatriz(FILE *Archivo);
void ArchImprimeContenido(FILE
*Archivo);
int main(int argc, char* argv[]){
//Definiendo las matrices a trabajar
int MatrizResultado[15][15];
int i,j;
int Matriz1[15][15],Matriz2[15][15];
FILE
*ArchMatriz1=fopen("mat1.txt","r");
FILE
*ArchMatriz2=fopen("mat2.txt","r");
if (ArchMatriz1==NULL ||
ArchMatriz2==NULL){
printf("Error al cargar los
archivos\n");
exit(0);
}
//Obtener de los archivos las matrices
for(i=0; i<15; i++){
for(j=0; j<15; j++){
fscanf(ArchMatriz1,"%d",&Matriz1[i]
[j]);
fscanf(ArchMatriz2,"%d",&Matriz2[i]
[j]);

}
}
fclose(ArchMatriz1);
fclose(ArchMatriz2);
//Creando la memoria compartida.
int sharedMemoryID;
key_t llave=1001;
int *shadress, *shauxiliar, *shproceed;
if((sharedMemoryID = shmget(llave,
MATRIXBYTES , IPC_CREAT | 0666)) < 0)
{
perror("Error al obtener la
memoria compartida: shmget");
return -1;
}
if((shadress = shmat(sharedMemoryID,
NULL, 0)) == (int *)-1)
{
perror("Error al enlazar la memoria
compartida: shmat");
return -1;
}
//Agregando los valores a la memoria
compartida
shauxiliar= shadress;
for(i=0; i<15; i++)
{
for(j=0; j<15; j++)
{
*shauxiliar++=Matriz1[i][j];
}
}
shproceed=shauxiliar;
for(i=0; i<15; i++)
{
for(j=0; j<15; j++)
{
*shauxiliar++=Matriz2[i][j];
}
}
//Declarando arreglos para las
operacion realizadas por la familia
int MatrizSumaResultado[15][15];
int MatrizMultResultado[15][15];
//Esperando a que el nieto acabe su
operacion respectiva
while(*shproceed != '*')
{
sleep(1);

}
//Obteniendo los valores de la
operacion del nieto de la memoria
compartida
shauxiliar= shadress;
for(i=0; i<15; i++)
{
for(j=0; j<15; j++)
{
MatrizMultResultado[i]
[j]=*shauxiliar++;
}
}
//Dandole luz verde al hijo
*shproceed='#';
//Ahora esperando a que el hijo acabe
de colocar su matriz respectiva
while(*shproceed != '*')
{
sleep(1);
}
//Obteniendo los valores de la
operacion del hijo de la memoria
compartida
shauxiliar= shadress;
for(i=0; i<15; i++)
{
for(j=0; j<15; j++)
{
MatrizSumaResultado[i]
[j]=*shauxiliar++;
}
}
//Finalmente, sacando su inversa y
guardandolo en un archivo
float InvMatrizSumaResultado[15][15];
float InvMatrizMultResultado[15][15];
FILE
*MatrizInversaPorHijo=fopen("MatrizInv
ersaPorHijo","w");
FILE
*MatrizInversaPorNieto=fopen("MatrizIn
versaPorNieto","w");
if(InversaMatriz(MatrizSumaResultado,
InvMatrizSumaResultado)==1)
{
ArchPutsMatrizFloat(MatrizInversaPorHijo
,InvMatrizSumaResultado);

}
else
{
fprintf(MatrizInversaPorHijo,"No tiene
inversa");
}
if(InversaMatriz(MatrizMultResultado,
InvMatrizMultResultado)==1)
{
ArchPutsMatrizFloat(MatrizInversaPorNiet
o,InvMatrizMultResultado);
}
else
{
fprintf(MatrizInversaPorNieto,"No
tiene inversa");
}
return 0;
}
void MultiplicaMatrices(int a[][15],int
b[][15],int r[][15]){
int i,j,k;
for(i=0;i<15;i++){
for (j=0;j<15;j++){
r[i][j]=0;
for(k=0;k<15;k++){
r[i][j]+= a[i][k] * b[k][j];
}
}
}
}
int InversaMatriz(int a[][15], float
matrizDeInversa[][15]){
int i, j, k , terminosIguales=0,
orden=15;
float pivote=0,
matrizDeIdentidad[orden][orden],
dividendo=0;
//Inicializando matriz identidad
for(i=0;i<orden;i++){
for(j=0;j<orden;j++){
if(i==j){
matrizDeInversa[i][j]=1;
}
else{
matrizDeInversa[i][j]=0;
}

}
}
//Copiar matriz recibida entera en la
flotante
for(i=0;i<orden;i++){
for(j=0;j<orden;j++){
matrizDeIdentidad[i][j]=(float)a[i]
[j];
}
}
//Iniciar el algoritmo de obtener la
inversa por Gauss Jordan
//Volviendola triangular inferior
for(i=0;i<orden;i++){
pivote=matrizDeIdentidad[i][i];
for(j=i;j<orden-1;j++){
dividendo= matrizDeIdentidad[j+1]
[i];
terminosIguales=0;
for(k=0;k<orden;k++){
if(matrizDeIdentidad[j+1]
[k]==matrizDeIdentidad[i][k]){
terminosIguales++;
if(terminosIguales==orden){
return 0;
}
}
matrizDeIdentidad[j+1][k]=(
(pivote/dividendo) *
matrizDeIdentidad[j+1][k] )matrizDeIdentidad[i][k];
matrizDeInversa[j+1][k]=(
(pivote/dividendo) *
matrizDeInversa[j+1][k] )matrizDeInversa[i][k];
}
}
}
//Volviendola triangular superior y asi
volverla una matriz escalar (o puede que
ya de identidad)
for(i=orden-1;0<=i;i--){
pivote=matrizDeIdentidad[i][i];
for(j=i;0<j;j--){
dividendo= matrizDeIdentidad[j-1]
[i];
for(k=orden-1;0<=k;k--){
matrizDeIdentidad[j-1][k]=(
(dividendo/pivote) *
matrizDeIdentidad[i][k] )-

matrizDeIdentidad[j-1][k];
matrizDeInversa[j-1][k]=(
(dividendo/pivote) * matrizDeInversa[i]
[k] )- matrizDeInversa[j-1][k];
}
}
}
//Finalmente, la matriz inversa la
volvemos identidad dividiendola si es
escalar
for(i=0;i<orden;i++){
for(j=0;j<orden;j++){
matrizDeInversa[i]
[j]=matrizDeInversa[i]
[j]/matrizDeIdentidad[i][i];
}
}
return 1;
}
void ArchPutsMatriz(FILE *Archivo, int
Matriz[][15]){
int i,j;
for (i=0;i<15;i++){
for(j=0;j<15;j++){
fprintf(Archivo,"%d ",Matriz [i][j]);
}
fprintf(Archivo,"\n");
}
}

void ArchPutsMatrizFloat(FILE *Archivo,


float Matriz[][15]){
int i,j;
for (i=0;i<15;i++){
for(j=0;j<15;j++){
fprintf(Archivo,"%f ",Matriz [i][j]);
}
fprintf(Archivo,"\n");
}
}
void ArchImprimeMatriz(FILE *Archivo){
int i,j,a[15][15];
for(i=0; i<15; i++){
for(j=0; j<15; j++){
fscanf(Archivo,"%d",&a[i][j]);
printf("%d ",a[i][j]);
}
printf("\n");
}
}
void ArchImprimeContenido(FILE
*Archivo){
char Caracter;
while(!feof(Archivo)){
fscanf(Archivo,"%c",&Caracter);
printf("%c",Caracter);
}
printf("\n");
}

/*hijo.c*/
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#define MATRIXBYTES 400
/*
Orden de ejecucion:
1.- Padre
2.- Hijo
3.- Nieto
*/

void SumaMatrices(int a[][15],int b[]


[15],int r[][15]);
int main(int argc, char* argv[])
{
//Creando la memoria compartida.
int sharedMemoryID;
key_t llave=1001;
int *shadress, *shauxiliar, *shproceed;
if((sharedMemoryID = shmget(llave,
MATRIXBYTES , IPC_CREAT | 0666)) < 0)
{
perror("Error al obtener la
memoria compartida: shmget");
return -1;
}

if((shadress = shmat(sharedMemoryID,
NULL, 0)) == (int *)-1)
{
perror("Error al enlazar la memoria
compartida: shmat");
return -1;
}
//Obteniendo los valores de la memoria
compartida
shauxiliar= shadress;
int Matriz1[15][15], Matriz2[15][15];
int i,j;
FILE
*ArchMatriz1=fopen("mat1.txt","r");
ILE
*ArchMatriz2=fopen("mat2.txt","r");
if (ArchMatriz1==NULL ||
ArchMatriz2==NULL){
printf("Error al cargar los
archivos\n");
exit(0);
}
//Obtener de los archivos las matrices
for(i=0; i<15; i++){
for(j=0; j<15; j++){
fscanf(ArchMatriz1,"%d",&Matriz1[i]
[j]);
fscanf(ArchMatriz2,"%d",&Matriz2[i]
[j]);
}
}
fclose(ArchMatriz1);
fclose(ArchMatriz2);
for(i=0; i<15; i++)
{
for(j=0; j<15; j++)
{
Matriz1[i][j]=*shauxiliar++;
}
}
shproceed=shauxiliar;
for(i=0; i<15; i++)
{
for(j=0; j<15; j++)
{
Matriz2[i][j]=*shauxiliar++;
}
}
//Realizando Operaciones

int MatrizSumaResultado[15][15];
SumaMatrices(Matriz1,Matriz2,MatrizSu
maResultado);
//Definiendo la matriz a operar
int Matriz3[15][15],Matriz4[15][15];
FILE
*ArchMatriz3=fopen("mat3.txt","r");
FILE
*ArchMatriz4=fopen("mat4.txt","r");
if (ArchMatriz3==NULL ||
ArchMatriz4==NULL){
printf("Error al cargar los
archivos\n");
exit(0);
}
//Obtener de los archivos las matrices
for(i=0; i<15; i++){
for(j=0; j<15; j++){
fscanf(ArchMatriz3,"%d",&Matriz3[i]
[j]);
fscanf(ArchMatriz4,"%d",&Matriz4[i]
[j]);
}
}
fclose(ArchMatriz3);
fclose(ArchMatriz4);
//Agregando los valores a la memoria
compartida
shauxiliar= shadress;
for(i=0; i<15; i++)
{
for(j=0; j<15; j++)
{
*shauxiliar++=Matriz3[i][j];
}
}
for(i=0; i<15; i++)
{
for(j=0; j<15; j++)
{
*shauxiliar++=Matriz4[i][j];
}
}
while(*shproceed != '#')
{
sleep(1);
}
//Agregando los valores de la operacion

respectiva a la memoria compartida


shauxiliar= shadress;
for(i=0; i<15; i++)
{
for(j=0; j<15; j++)
{
*shauxiliar+
+=MatrizSumaResultado[i][j];
}
}
*shproceed='*';
return 0;

}
void SumaMatrices(int a[][15],int b[]
[15],int r[][15]){
int i,j;
for (i=0;i<15;i++){
for(j=0;j<15;j++){
r[i][j]=a[i][j] + b[i][j];
}
}
}

/*nieto.c*/
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#define MATRIXBYTES 400
/*
Orden de ejecucion:
1.- Padre
2.- Hijo
3.- Nieto
*/
void MultiplicaMatrices(int a[][15],int
b[][15],int r[][15]);
int main(int argc, char* argv[])
{
//Creando la memoria compartida.
int sharedMemoryID;
key_t llave=1001;
int *shadress, *shauxiliar, *shproceed;
if((sharedMemoryID = shmget(llave,
MATRIXBYTES , IPC_CREAT | 0666)) < 0)
{
perror("Error al obtener la
memoria compartida: shmget");
return -1;
}
if((shadress = shmat(sharedMemoryID,
NULL, 0)) == (int *)-1)

{
perror("Error al enlazar la memoria
compartida: shmat");
return -1;
}
//Obteniendo los valores de la memoria
compartida
int Matriz3[15][15], Matriz4[15][15];
int i,j;
shauxiliar= shadress;
for(i=0; i<15; i++)
{
for(j=0; j<15; j++)
{
Matriz3[i][j]=*shauxiliar++;
}
}
shproceed=shauxiliar;
for(i=0; i<15; i++)
{
for(j=0; j<15; j++)
{
Matriz4[i][j]=*shauxiliar++;
}
}
//Realizando Operaciones
int MatrizMultResultado[15][15];
MultiplicaMatrices(Matriz3,Matriz4,Matriz
MultResultado);
//Agregando los valores de la operacion
respectiva a la memoria compartida

shauxiliar= shadress;

void MultiplicaMatrices(int a[][15],int

for(i=0; i<15; i++)


{
for(j=0; j<15; j++)
{
*shauxiliar+
+=MatrizMultResultado[i][j];
}
}
*shproceed='*';
return 0;
}

b[][15],int r[][15]){
int i,j,k;
for(i=0;i<15;i++){
for (j=0;j<15;j++){
r[i][j]=0;
for(k=0;k<15;k++){
r[i][j]+= a[i][k] * b[k][j];
}
}
}
}

Pantalla de ejecucin

3.- Buenda Moreno Hugo Vidal


Seccin Windows
Cdigo fuente

/*cliente.c*/

#include <windows.h>
#include <stdio.h>
#define TAM_MEM 200
#define TAM_MEM2 100
#define TAM_MATRIZ 10
void llenarMatrices(int M1[TAM_MATRIZ]
[TAM_MATRIZ],
int
M2[TAM_MATRIZ]
[TAM_MATRIZ]);
int main(void)
{
HANDLE hArchMapeo, hArchMapeo2,
hArchMapeo3;
char *idMemCompartida =
"MemoriaCompartida";
char *idMemCompartida2 =
"MemoriaCompartida2";
char *idMemCompartida3 =
"MemoriaCompartida3";
int *apDatos, *apTrabajo, c,
*apDatos2, *apTrabajo2;
int *apDatos3, *apTrabajo3;
int M1[TAM_MATRIZ][TAM_MATRIZ];
int M2[TAM_MATRIZ][TAM_MATRIZ];
int N1[TAM_MATRIZ][TAM_MATRIZ];
int N2[TAM_MATRIZ][TAM_MATRIZ];
int multiplicacion[TAM_MATRIZ]
[TAM_MATRIZ];
int i = 0, j = 0, com = 0;
llenarMatrices(N1,N2); //Proceso
para enviar datos al Nieto
if((hArchMapeo3 = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
TAM_MEM,
idMemCompartida3)
) == NULL)
{
printf("No se mapeo la
memoria
compartida
(%i)\n",
GetLastError());
exit(-1);
}

if((apDatos3
=
(int*)MapViewOfFile(hArchMapeo3,
FILE_MAP_ALL_ACCESS,
0,
0,
TAM_MEM)) == NULL)
{
printf("No se creo la memoria
compartida: (%i)\n", GetLastError());
CloseHandle(hArchMapeo3);
exit(-1);
}
apTrabajo3 = apDatos3;
for(i = 0; i < TAM_MATRIZ; i++)
{
for(j = 0; j < TAM_MATRIZ;
j++)
*apTrabajo3++ = N1[i]
[j];
}
for(i = 0; i < TAM_MATRIZ; i++)
{
for(j = 0; j < TAM_MATRIZ;
j++)
*apTrabajo3++ = N2[i]
[j];
}
*apTrabajo3 = 599;
while(*apDatos3 != 600)
sleep(1);
UnmapViewOfFile(apDatos3);
CloseHandle(hArchMapeo3);
if((hArchMapeo = OpenFileMapping(
FILE_MAP_ALL_ACCESS,
FALSE,
idMemCompartida)
)== NULL)
{
printf("No se abrio archivo de
mapeo de la memoria compartida:
(%i)\n",GetLastError());
exit(-1);
}
if((apDatos
=
(int*)
MapViewOfFile(hArchMapeo,

FILE_MAP_ALL_ACCESS,
0,
0,
TAM_MEM)) == NULL)
{
printf("No se accedio a la
memoria
compartida:
(%i)\n",GetLastError());
CloseHandle(hArchMapeo);
exit(-1);
}
i = 0;
j = 0;
com = 0;
for(apTrabajo = apDatos; *apTrabajo !
= 29; apTrabajo++)
{
if(i == 9 && j == 10)
{
com = 1;
j = 0;
i = 0;
}
if(com == 0)
{
if(j == 10)
{
i++;
j = 0;
}
M1[i][j] = *apTrabajo;
j++;
}
else if(com != 0)
{
if(j == 10)
{
i++;
j = 0;
}
M2[i][j] = *apTrabajo;
j++;
}
}

for(j = 0; j < TAM_MATRIZ;


j++)
printf("%d ",M1[i][j]);
}
printf("\n\n");
for(i = 0; i < TAM_MATRIZ; i++)
{
printf("\n");
for(j = 0; j < TAM_MATRIZ;
j++)
printf("%d ",M2[i][j]);
}
putchar('\n');
*apDatos = 30;
UnmapViewOfFile(apDatos);
CloseHandle(hArchMapeo);
for(i = 0; i < TAM_MATRIZ; i++)
{
for(j = 0; j < TAM_MATRIZ;
j++)
multiplicacion[i][j] =
M1[i][j] * M2[i][j];
}
//Envia datos de multiplicacion al
padre
if((hArchMapeo2 = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
TAM_MEM2,
idMemCompartida2)
) == NULL)
{
printf("No se mapeo la
memoria
compartida
(%i)\n",
GetLastError());
exit(-1);
}
if((apDatos2
=
(int*)MapViewOfFile(hArchMapeo,
FILE_MAP_ALL_ACCESS,

for(i = 0; i < TAM_MATRIZ; i++)


{
printf("\n");

0,

0,

*apTrabajo2 = 499;

TAM_MEM2)) == NULL)

while(*apDatos2 != 500)
sleep(1);
UnmapViewOfFile(apDatos2);
CloseHandle(hArchMapeo2);

{
printf("No se creo la memoria
compartida: (%i)\n", GetLastError());
CloseHandle(hArchMapeo2);
exit(-1);
}
apTrabajo2 = apDatos2;

for(i = 0; i < TAM_MATRIZ; i++)


{
for(j = 0; j < TAM_MATRIZ;
j++)
*apTrabajo2++ =
multiplicacion[i][j];
}

exit(0);
}
void llenarMatrices(int M1[TAM_MATRIZ]
[TAM_MATRIZ],
int
M2[TAM_MATRIZ]
[TAM_MATRIZ])
{
int x, y;
srand(time(NULL));
for(x = 0; x < TAM_MATRIZ; x++)
for(y
=
0;
y
<
TAM_MATRIZ; y++)
M1[x][y] = rand() %
21;
for(x = 0; x < TAM_MATRIZ; x++)
for(y
=
0;
y
<
TAM_MATRIZ; y++)
M2[x][y] = rand() %
21

/*Servidor.c*/
#include <windows.h>
#include <stdio.h>
#define TAM_MEM 200
#define TAM_MEM2 100
#define TAM_MATRIZ 10

void llenarMatrices(int M1[TAM_MATRIZ]


[TAM_MATRIZ],
int
M2[TAM_MATRIZ]
[TAM_MATRIZ]);
void
calcularCofactores(int
**M_cofactores, int tam);

**M,int

void llenarMatrices(int M1[TAM_MATRIZ]


[TAM_MATRIZ],
int
M2[TAM_MATRIZ]
[TAM_MATRIZ]);

int main(void)
{

if((hArchMapeo = CreateFileMapping(

HANDLE hArchMapeo, hArchMapeo2,


hArchMapeo3;

INVALID_HANDLE_VALUE,
NULL,

char *idMemCompartida
"MemoriaCompartida";

char *idMemCompartida2
"MemoriaCompartida2";

char *idMemCompartida4
"MemoriaCompartida4";

int *apDatos, *apTrabajo,


*apDatos2, *apTrabajo2;

c,

PAGE_READWRITE,
0,
TAM_MEM,
idMemCompartida)

int *apDatos4, *apTrabajo4;


int i, j, det;
int M1 [TAM_MATRIZ][TAM_MATRIZ];

) == NULL)
{

memoria
GetLastError());

exit(-1);

int M2 [TAM_MATRIZ][TAM_MATRIZ];
int multiplicacion[TAM_MATRIZ]
[TAM_MATRIZ];
int suma[TAM_MATRIZ][TAM_MATRIZ];

printf("No se mapeo la
compartida
(%i)\n",

}
if((apDatos
(int*)MapViewOfFile(hArchMapeo,

FILE_MAP_ALL_ACCESS,

int **M_inversa1 = NULL;

0,

int **M_inversa2 = NULL;

0,

int **M_cofactores = NULL;

TAM_MEM)) == NULL)

FILE *archivo;
{

llenarMatrices(M1,M2);

printf("No se creo la memoria


compartida: (%i)\n", GetLastError());

CloseHandle(hArchMapeo);

CloseHandle(hArchMapeo);

exit(-1);
}

if((hArchMapeo2 = OpenFileMapping(

apTrabajo = apDatos;

FILE_MAP_ALL_ACCESS,
FALSE,

for(i = 0; i < TAM_MATRIZ; i++)

idMemCompartida2)

)== NULL)
for(j = 0; j < TAM_MATRIZ;

j++)
*apTrabajo++ = M1[i]
[j];

{
printf("No se abrio archivo de
mapeo de la memoria compartida:
(%i)\n",GetLastError());

exit(-1);
}

for(i = 0; i < TAM_MATRIZ; i++)

if((apDatos2
MapViewOfFile(hArchMapeo,

(int*)

{
FILE_MAP_ALL_ACCESS,
for(j = 0; j < TAM_MATRIZ;
j++)

0,
*apTrabajo++ = M2[i]

0,

[j];
TAM_MEM2)) == NULL)
}
{
*apTrabajo = 29;
while(*apDatos != 30)

printf("No se accedio a la
memoria
compartida:
(%i)\n",GetLastError());

sleep(1);
CloseHandle(hArchMapeo2);
UnmapViewOfFile(apDatos);
exit(-1);

for(j = 0; j < TAM_MATRIZ;


j++)

i = 0;
printf("%d
",multiplicacion[i][j]);

j = 0;
for(apTrabajo2 = apDatos2;
*apTrabajo2 != 499; apTrabajo2++)

}
printf("\n\n");

{
//Obtener iformacin de la suma
if(j == 10)
if((hArchMapeo3 = OpenFileMapping(
{
FILE_MAP_ALL_ACCESS,
i++;
FALSE,
j = 0;
idMemCompartida4)
}
)== NULL)
multiplicacion[i][j] = *apTrabajo2;
{
j++;
printf("No se abrio archivo de
mapeo de la memoria compartida:
(%i)\n",GetLastError());

}
putchar('\n');

exit(-1);

*apDatos2 = 500;
UnmapViewOfFile(apDatos2);
CloseHandle(hArchMapeo2);

}
if((apDatos4
=
MapViewOfFile(hArchMapeo3,
FILE_MAP_ALL_ACCESS,
0,

for(i = 0; i < TAM_MATRIZ; i++)

0,

TAM_MEM2)) == NULL)

printf("\n");
{

(int*)

printf("No se accedio a la
memoria
compartida:
(%i)\n",GetLastError());

for(i = 0; i < TAM_MATRIZ; i++)


{

CloseHandle(hArchMapeo3);

printf("\n");

exit(-1);

for(j = 0; j < TAM_MATRIZ;


j++)

}
printf("%d ",suma[i][j]);
i = 0;
}
j = 0;
//Calculo de las matrices inversas
for(apTrabajo4 = apDatos4;
*apTrabajo4 != 699; apTrabajo4++)

M_inversa1 = (int **)malloc(sizeof(int


*) * TAM_MATRIZ);

{
if(j == 10)
{

M_inversa2
=
(int
**)malloc(sizeof(int *) * TAM_MATRIZ);
M_cofactores
=
(int
**)malloc(sizeof(int *) * TAM_MATRIZ);

i++;
for(i = 0; i < TAM_MATRIZ; i++)
j = 0;
{
}
suma[i][j] = *apTrabajo4;
j++;
}
putchar('\n');

M_inversa1[i]
=
*)malloc(sizeof(int) * TAM_MATRIZ);

(int

M_inversa2[i]
=
*)malloc(sizeof(int) * TAM_MATRIZ);

(int

M_cofactores[i]
=
*)malloc(sizeof(int) * TAM_MATRIZ);

(int

*apDatos4 = 700;

UnmapViewOfFile(apDatos4);

for(i = 0; i < TAM_MATRIZ; i++)

CloseHandle(hArchMapeo3);

for(j = 0; j < TAM_MATRIZ;


j++)
{

M_inversa1[i][j]

multiplicacion[i][j];

M_inversa1[i]
[j] = M_cofactores[j][i];

M_inversa2[i][j]

suma[i][j];

M_inversa1[i]
[j] /= det;

det
determinanteRecursivo(M_inversa1,
TAM_MATRIZ);

if(det == 0) //Si la matriz 1 no


tiene inversa.
{
for(i = 0; i < TAM_MATRIZ;
i++)
for(j

0;

det
determinanteRecursivo(M_inversa2,
TAM_MATRIZ);

if(det == 0) //Si la matriz 2 no


tiene inversa.
{

<

TAM_MATRIZ; j++)

for(i = 0; i < TAM_MATRIZ;


M_inversa1[i]

i++)

[j] = 0;

for(j

0;

<

TAM_MATRIZ; j++)

M_inversa2[i]

else

[j] = 0;

}
else

calcularCofactores(M_inversa1,
M_cofactores, TAM_MATRIZ);

for(i = 0; i < TAM_MATRIZ;


i++)
for(j

0;

<

calcularCofactores(M_inversa2,
M_cofactores, TAM_MATRIZ);

TAM_MATRIZ; j++)

for(i = 0; i < TAM_MATRIZ;


{

i++)
for(j
TAM_MATRIZ; j++)

0;

<

fprintf(archivo,"\n");
M_inversa2[i]

for(j = 0; j < TAM_MATRIZ; j++)

[j] = M_cofactores[j][i];
fprintf(archivo,"%d
M_inversa2[i]

", M_inversa2[i][j]);

[j] /= det;
}
}
}
for(i = 0; i < TAM_MATRIZ; i++)

//Crea los archivos txt


archivo
fopen("inversa1.txt","w+");

free(M_inversa1[i]);
free(M_inversa2[i]);

for(i = 0; i < TAM_MATRIZ; i++)

free(M_cofactores[i]);

fprintf(archivo,"\n");

free(M_inversa1);

for(j = 0; j < TAM_MATRIZ; j++)

free(M_inversa2);

fprintf(archivo,"%d

free(M_cofactores);

", M_inversa1[i][j]);
}

getchar();
exit(0);

fclose(archivo);
archivo = fopen("inversa2.txt","w+");

for(i = 0; i < TAM_MATRIZ; i++)

void llenarMatrices(int M1[TAM_MATRIZ]


[TAM_MATRIZ],
int
M2[TAM_MATRIZ]
[TAM_MATRIZ])

{
{

int x, y;
srand(time(NULL));

//Caso base.

for(x = 0; x < TAM_MATRIZ; x++)

if(tam == 2)

for(y
TAM_MATRIZ; y++)

0;

<

M1[x][y] = rand() %
21;

{
for(i = 0; i < (tam - 1); i+
+)
free(M_aux[i]);
free(M_aux);

for(x = 0; x < TAM_MATRIZ; x++)


for(y
TAM_MATRIZ; y++)

0;

<

return M[0][0] * M[1][1] M[0][1] * M[1][0];


}

M2[x][y] = rand() %
21;

//Parte recursiva.

for(i = 0; i < tam; i++)


{

int determinanteRecursivo(int **M, int


tam)

for(j = 1; j < tam; j++)


{

a = 0;

int **M_aux = NULL;

for(k = 0; k < tam;

int det = 0, i, j, k, a;

k++)
if(k != i)

M_aux = (int **)malloc(sizeof(int


*) * (tam - 1));
for(i = 0; i < (tam - 1); i++)
M_aux[i]
=
*)malloc(sizeof(int) * (tam - 1));

M_aux[j - 1][a++] = M[j][k];


}

(int

det += M[0][i] * (int)pow(1.0,


(2
+
i))
*
determinanteRecursivo(M_aux, tam - 1);

for(j = 0; j < tam; j++)


{

a = 0;
for(k = 0; k < tam;
k++)

for(i = 0; i < (tam - 1); i++)


{
free(M_aux[i]);
if(k != i)
free(M_aux);
{
return det;
b = 0;
}
for(l
= 0; l < tam; l++)
void calcularCofactores(int
**M_cofactores, int tam)

**M,

int
if(l != j)

{
M_aux[a][b++] = M[k][l];
int i, j, k, l, a, b, det = 0;
a++;
int **M_aux;
}
}
M_aux = (int **)malloc(sizeof(int
*) * (tam - 1));

det
=
determinanteRecursivo(M_aux, tam - 1);

for(i = 0; i < tam - 1; i++)


M_aux[i]
=
*)malloc(sizeof(int) * (tam - 1));

(int

M_cofactores[i][j] =
det * (int)pow(-1.0, (i + j + 2));
}

for(i = 0; i < tam; i++)


{

for(i = 0; i < tam - 1; i++)

free(M_aux);

free(M_aux[i]);

/*Nieto.c*/
#include <windows.h>

if((hArchMapeo = OpenFileMapping(

#include <stdio.h>

FILE_MAP_ALL_ACCESS,

#define TAM_MEM 200

FALSE,

#define TAM_MEM2 100

idMemCompartida3)

#define TAM_MATRIZ 15

)== NULL)
{

int main(void)

printf("No se abrio archivo de


mapeo de la memoria compartida:
(%i)\n",GetLastError());

exit(-1);

HANDLE hArchMapeo, hArchMapeo2;


char *idMemCompartida3
"MemoriaCompartida3";
char *idMemCompartida4
"MemoriaCompartida4";

if((apDatos3
MapViewOfFile(hArchMapeo,

(int*)

FILE_MAP_ALL_ACCESS,
int *apDatos3,
*apDatos2, *apTrabajo2;

*apTrabajo3,
0,

int M1[TAM_MATRIZ][TAM_MATRIZ];

0,

int M2[TAM_MATRIZ][TAM_MATRIZ];

TAM_MEM)) == NULL)

int suma[TAM_MATRIZ][TAM_MATRIZ];
int i = 0, j = 0, com = 0;

{
printf("No se accedio a la
memoria
compartida:
(%i)\n",GetLastError());
CloseHandle(hArchMapeo);

exit(-1);

else if(com != 0)

i = 0;

j = 0;

if(j == 10)

com = 0;

for(apTrabajo3 = apDatos3;
*apTrabajo3 != 599; apTrabajo3++)

i++;
j = 0;

{
}
if(i == 9 && j == 10)
M2[i][j] = *apTrabajo3;
{
j++;
com = 1;
}
j = 0;
}
i = 0;
}
if(com == 0)

for(i = 0; i < TAM_MATRIZ; i++)


{

printf("\n");

if(j == 10)

for(j = 0; j < TAM_MATRIZ;

j++)
i++;

printf("%d ",M1[i][j]);

j = 0;

printf("\n\n");

M1[i][j] = *apTrabajo3;

for(i = 0; i < TAM_MATRIZ; i++)

j++;

printf("\n");

INVALID_HANDLE_VALUE,

for(j = 0; j < TAM_MATRIZ;

NULL,

j++)
PAGE_READWRITE,
printf("%d ",M2[i][j]);
0,
}
TAM_MEM2,
idMemCompartida4)
for(i = 0; i < TAM_MATRIZ; i++)
) == NULL)
{
{
for(j = 0; j < TAM_MATRIZ;
printf("No se mapeo la
memoria
compartida
(%i)\n",
GetLastError());

j++)
{

exit(-1);

suma[i][j] = M1[i][j] +
M2[i][j];

}
}
if((apDatos2
(int*)MapViewOfFile(hArchMapeo2,

FILE_MAP_ALL_ACCESS,
*apDatos3 = 600;

0,

UnmapViewOfFile(apDatos3);

0,

CloseHandle(hArchMapeo);

TAM_MEM2)) == NULL)
{
printf("No se creo la memoria
compartida: (%i)\n", GetLastError());

//Comparte datos con el padre

CloseHandle(hArchMapeo2);
if((hArchMapeo2
CreateFileMapping(

exit(-1);

apTrabajo2 = apDatos2;
*apTrabajo2 = 699;
for(i = 0; i < TAM_MATRIZ; i++)

while(*apDatos2 != 700)

sleep(1);
for(j = 0; j < TAM_MATRIZ;

UnmapViewOfFile(apDatos2);

j++)

CloseHandle(hArchMapeo2);

exit(0);

*apTrabajo2++ =
suma[i][j];
}

Pantalla de ejecucin

También podría gustarte