You are on page 1of 34

Sección Windows:

4. Capture, compile y ejecute el siguiente programa de creación de hilos en Windows. Observe el


funcionamiento.

Código:

#include <windows.h>
#include <stdio.h>

DWORD WINAPI funcionHilo(LPVOID lpParam);


typedef struct Informacion{
int val_1;
int val_2;
} info;

int main(void){
DWORD idHilo;
HANDLE manHilo;
info argumentos;
argumentos.val_1=10;
argumentos.val_2=100;

//Creacion del hilo


manHilo=CreateThread(NULL,0,funcionHilo,&argumentos,0,&idHilo);

//Espera la finalizacion del hilo


WaitForSingleObject(manHilo,INFINITE);

printf("Valores al salir del Hilo: %i


%i\n",argumentos.val_1,argumentos.val_2);

//Cierre del manejador del hilo


CloseHandle(manHilo);
return 0;
}

DWORD WINAPI funcionHilo(LPVOID lpParam){


info *datos=(info*)lpParam;
printf("Valores al entrar al Hilo: %i %i\n",datos->val_1,datos->val_2);
datos->val_1*=2;
datos->val_2*=2;
return 0;
}

Pantalla de Salida:
Observaciones:

En este programa lo que nos dimos cuenta es que al momento de la creación de procesos
debemos de tener ciertos parámetros, los cuales vamos a darles un valor para poder crear
el hilo y poder efectuar una operación como lo hace este programa, en este caso
observamos que en la función de hilos tenemos que acceder al espacio de memoria donde
se tiene almacenado el valor que previamente se había dado y en la función del hilo
accedemos a ese espacio de memoria para poder obtener el valor y multiplicarlo.

5. Programe una aplicación (tanto en Linux como en Windows), que cree un proceso hijo a partir
de un proceso padre, el hijo creado a su vez creará 15 hilos. A su vez cada uno de los 10 hilos
creará 5 hilos más. Cada uno de los hilos creados imprimirá en pantalla “Practica 5” si se trata de
un hilo terminal o los identificadores de los hilos creados si se trata de un proceso o hilo padre.

Código:

Proceso Padre:

#include <windows.h>
#include <stdio.h>

void main(){
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si,sizeof(si));
si.cb=sizeof(si);
ZeroMemory(&pi,sizeof(pi));

//Creacion de el proceso hijo


if(!CreateProcess(NULL,"ProcesoHijo",NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)){
printf("Fallo al invocar CreateProcess(%d)\n",GetLastError());
return;
}
//Proceso Padre
printf("Soy el padre\n");
WaitForSingleObject(pi.hProcess,INFINITE);

//Terminacion controlada del proceso e hilo asociado de ejecucion


CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}

Proceso Hijo:

#include <windows.h>
#include <stdio.h>

void main(){

STARTUPINFO no;
PROCESS_INFORMATION po;
int j;
ZeroMemory(&no,sizeof(no));
no.cb=sizeof(no);
ZeroMemory(&po,sizeof(po));

//Creacion de los procesos hijos


if(!CreateProcess(NULL,"ProcesoNietos",NULL,NULL,FALSE,0,NULL,NULL,&no,&po)){
printf("Fallo al invocar CreateProcess(%d)\n",GetLastError());
return;
}

printf("\tSoy el hijo\n");
WaitForSingleObject(po.hProcess,INFINITE);

//Terminacion controlada del proceso e hilo asociado de ejecucion


CloseHandle(po.hProcess);
CloseHandle(po.hThread);
}

Proceso Nieto:

#include <windows.h>
#include <tchar.h>
#include <strsafe.h>

#define BUF_SIZE 2048


#define MAX_THREADS 15
#define MAX_S_THREADS 10
#define MAX_S2_THREADS 5

DWORD WINAPI MyThreadFunction( LPVOID lpParam );


DWORD WINAPI SMyThreadFunction( LPVOID lpParam );
DWORD WINAPI S2MyThreadFunction( LPVOID lpParam );
void ErrorHandler(LPTSTR lpszFunction);
void Pruebas();
void Pruebas2();
typedef struct MyData {
int val1;
int val2;
} MYDATA, *PMYDATA;

int _tmain()
{
PMYDATA pDataArray[MAX_THREADS];
DWORD dwThreadIdArray[MAX_THREADS];
HANDLE hThreadArray[MAX_THREADS];

// Create MAX_THREADS worker threads.


int i;
for( i=0; i<MAX_THREADS; i++ )
{
// Allocate memory for thread data.

pDataArray[i] = (PMYDATA) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,


sizeof(MYDATA));

if( pDataArray[i] == NULL )


{
// If the array allocation fails, the system is out of memory
// so there is no point in trying to print an error message.
// Just terminate execution.
ExitProcess(2);
}

// Generate unique data for each thread to work with.

pDataArray[i]->val1 = i;
pDataArray[i]->val2 = i+100;

// Create the thread to begin execution on its own.

hThreadArray[i] = CreateThread(
NULL, // default security attributes
0, // use default stack size
MyThreadFunction, // thread function name
pDataArray[i], // argument to thread function
0, // use default creation flags
&dwThreadIdArray[i]); // returns the thread identifier

// Check the return value for success.


// If CreateThread fails, terminate execution.
// This will automatically clean up threads and memory.

if (hThreadArray[i] == NULL)
{
ErrorHandler(TEXT("CreateThread"));
ExitProcess(3);
}

Pruebas();
} // End of main thread creation loop.

// Wait until all threads have terminated.

WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);

// Close all thread handles and free memory allocations.

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


{
CloseHandle(hThreadArray[i]);
if(pDataArray[i] != NULL)
{
HeapFree(GetProcessHeap(), 0, pDataArray[i]);
pDataArray[i] = NULL; // Ensure address is not reused.
}
}

return 0;
}

DWORD WINAPI MyThreadFunction( LPVOID lpParam )


{
HANDLE hStdout;
PMYDATA pDataArray;

TCHAR msgBuf[BUF_SIZE];
size_t cchStringSize;
DWORD dwChars;

// Make sure there is a console to receive output results.

hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if( hStdout == INVALID_HANDLE_VALUE )
return 1;

// Cast the parameter to the correct data type.


// The pointer is known to be valid because
// it was checked for NULL before the thread was created.

pDataArray = (PMYDATA)lpParam;

// Print the parameter values using thread-safe functions.

StringCchPrintf(msgBuf, BUF_SIZE, TEXT("\t\tSoy el nieto = %d, %d\n"),


pDataArray->val1, pDataArray->val2);
StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);
WriteConsole(hStdout, msgBuf, (DWORD)cchStringSize, &dwChars, NULL);

return 0;
}

DWORD WINAPI SMyThreadFunction( LPVOID lpParam )


{
HANDLE hStdout;
PMYDATA pDataArray;
TCHAR msgBuf[BUF_SIZE];
size_t cchStringSize;
DWORD dwChars;

// Make sure there is a console to receive output results.

hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if( hStdout == INVALID_HANDLE_VALUE )
return 1;

// Cast the parameter to the correct data type.


// The pointer is known to be valid because
// it was checked for NULL before the thread was created.

pDataArray = (PMYDATA)lpParam;

// Print the parameter values using thread-safe functions.

StringCchPrintf(msgBuf, BUF_SIZE, TEXT("\t\t\tSoy el bisnieto = %d, %d\n"),


pDataArray->val1, pDataArray->val2);
StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);
WriteConsole(hStdout, msgBuf, (DWORD)cchStringSize, &dwChars, NULL);

return 0;
}

DWORD WINAPI S2MyThreadFunction( LPVOID lpParam )


{
HANDLE hStdout;
PMYDATA pDataArray;

TCHAR msgBuf[BUF_SIZE];
size_t cchStringSize;
DWORD dwChars;

// Make sure there is a console to receive output results.

hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if( hStdout == INVALID_HANDLE_VALUE )
return 1;

// Cast the parameter to the correct data type.


// The pointer is known to be valid because
// it was checked for NULL before the thread was created.

pDataArray = (PMYDATA)lpParam;

// Print the parameter values using thread-safe functions.

StringCchPrintf(msgBuf, BUF_SIZE, TEXT("\t\t\t\tPractica 5\n"),


pDataArray->val1, pDataArray->val2);
StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);
WriteConsole(hStdout, msgBuf, (DWORD)cchStringSize, &dwChars, NULL);

return 0;
}
void ErrorHandler(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code.

LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();

FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );

// Display the error message.

lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) lpszFunction) + 40) *
sizeof(TCHAR));

StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR) lpDisplayBuf, TEXT("Error"), MB_OK);

// Free error-handling buffer allocations.

LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}

void Pruebas(){
PMYDATA SpDataArray[MAX_S_THREADS];
DWORD SdwThreadIdArray[MAX_S_THREADS];
HANDLE ShThreadArray[MAX_S_THREADS];

// Create MAX_THREADS worker threads.


int j;
for( j=0; j<MAX_S_THREADS; j++ )
{
// Allocate memory for thread data.

SpDataArray[j] = (PMYDATA) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,


sizeof(MYDATA));

if( SpDataArray[j] == NULL )


{
// If the array allocation fails, the system is out of memory
// so there is no point in trying to print an error message.
// Just terminate execution.
ExitProcess(2);
}
// Generate unique data for each thread to work with.

SpDataArray[j]->val1 = j;
SpDataArray[j]->val2 = j+200;

// Create the thread to begin execution on its own.

ShThreadArray[j] = CreateThread(
NULL, // default security attributes
0, // use default stack size
SMyThreadFunction, // thread function name
SpDataArray[j], // argument to thread function
0, // use default creation flags
&SdwThreadIdArray[j]); // returns the thread identifier

// Check the return value for success.


// If CreateThread fails, terminate execution.
// This will automatically clean up threads and memory.

if (ShThreadArray[j] == NULL)
{
ErrorHandler(TEXT("CreateThread"));
ExitProcess(3);
}
Pruebas2();
} // End of main thread creation loop.

// Wait until all threads have terminated.

WaitForMultipleObjects(MAX_S_THREADS, ShThreadArray, TRUE, INFINITE);

// Close all thread handles and free memory allocations.

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


{
CloseHandle(ShThreadArray[j]);
if(SpDataArray[j] != NULL)
{
HeapFree(GetProcessHeap(), 0, SpDataArray[j]);
SpDataArray[j] = NULL; // Ensure address is not reused.
}
}
}

void Pruebas2(){
PMYDATA S2pDataArray[MAX_S2_THREADS];
DWORD S2dwThreadIdArray[MAX_S2_THREADS];
HANDLE S2hThreadArray[MAX_S2_THREADS];

// Create MAX_THREADS worker threads.


int j;
for( j=0; j<MAX_S2_THREADS; j++ )
{
// Allocate memory for thread data.
S2pDataArray[j] = (PMYDATA) HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(MYDATA));

if( S2pDataArray[j] == NULL )


{
// If the array allocation fails, the system is out of memory
// so there is no point in trying to print an error message.
// Just terminate execution.
ExitProcess(2);
}

// Generate unique data for each thread to work with.

S2pDataArray[j]->val1 = j;
S2pDataArray[j]->val2 = j+200;

// Create the thread to begin execution on its own.

S2hThreadArray[j] = CreateThread(
NULL, // default security attributes
0, // use default stack size
S2MyThreadFunction, // thread function name
S2pDataArray[j], // argument to thread function
0, // use default creation flags
&S2dwThreadIdArray[j]); // returns the thread identifier

// Check the return value for success.


// If CreateThread fails, terminate execution.
// This will automatically clean up threads and memory.

if (S2hThreadArray[j] == NULL)
{
ErrorHandler(TEXT("CreateThread"));
ExitProcess(3);
}
} // End of main thread creation loop.

// Wait until all threads have terminated.

WaitForMultipleObjects(MAX_S2_THREADS, S2hThreadArray, TRUE, INFINITE);

// Close all thread handles and free memory allocations.

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


{
CloseHandle(S2hThreadArray[j]);
if(S2pDataArray[j] != NULL)
{
HeapFree(GetProcessHeap(), 0, S2pDataArray[j]);
S2pDataArray[j] = NULL; // Ensure address is not reused.
}
}
}
Pantalla de Salida:
6. Programe la misma aplicación del punto 5 de la practica 4 pero utilizando hilos (tanto en Linux
como en Windows) en vez de procesos. Compare ambos programas (el creado en la práctica 4 y el
creado en esta práctica) y de sus observaciones tanto de funcionamiento como de los tiempos de
ejecución resultantes.

Código de Librería “inversa.h”:

#include <stdio.h>
int const Tam=100;
void PideDatos(int k,int Dim, float Sist[][Tam]);
void EscribeDatos(int Dim, float Sist[][Tam]);
void Invierte(int Dim, float Sist[][Tam], float Inv[][Tam]);
int F[3][3]={{2,0,1},{3,0,0},{5,1,1}};
int G[3][3]={{1,0,1},{1,2,1},{1,1,0}};

void InversaMatriz()
{
int C,Dimension=3,k=1;
float Sistema[Tam][Tam],Inversa[Tam][Tam];
PideDatos(k,Dimension,Sistema);
Invierte(Dimension,Sistema,Inversa);
printf("\n\n\nLa inversa de la matriz 1 es: \n\n");
EscribeDatos(Dimension,Inversa);
PideDatos(k+1,Dimension,Sistema);
Invierte(Dimension,Sistema,Inversa);
printf("\n\n\nLa inversa de la matriz 2 es: \n\n");
EscribeDatos(Dimension,Inversa);
}

void PideDatos(int k,int Dim,float Sist[][Tam])


{
int i,j;
if(k==1){
for(i=1;i<=Dim;i++) for(j=1;j<=Dim;j++){
Sist[i][j] = F[i-1][j-1];}
}
else{
for(i=1;i<=Dim;i++) for(j=1;j<=Dim;j++){
Sist[i][j] = G[i-1][j-1];}
}
}

void EscribeDatos(int Dim, float Sist[][Tam])


{
int A,B;
for(A=1;A<=Dim;A++){
for(B=1;B<=(Dim);B++) printf("%7.2f",Sist[A][B]);
printf("\n");
}}

void Invierte(int Dim, float Sist[][Tam], float Inv[][Tam])


{
int NoCero,Col,C1,C2,A;
float Pivote,V1,V2;

/*Se inicializa la matriz inversa, como la matriz identidad:*/


for(C1=1;C1<=Dim;C1++) for(C2=1;C2<=Dim;C2++)
if (C1==C2) Inv[C1][C2]=1; else Inv[C1][C2]=0;

for(Col=1;Col<=Dim;Col++){
NoCero=0;A=Col;
while(NoCero==0){
if((Sist[A][Col]>0.0000001)||((Sist[A][Col]<-0.0000001))){
NoCero=1;}
else A++;}
Pivote=Sist[A][Col];
for(C1=1;C1<=Dim;C1++){
V1=Sist[A][C1];
Sist[A][C1]=Sist[Col][C1];
Sist[Col][C1]=V1/Pivote;
V2=Inv[A][C1];
Inv[A][C1]=Inv[Col][C1];
Inv[Col][C1]=V2/Pivote;
}
for(C2=Col+1;C2<=Dim;C2++){
V1=Sist[C2][Col];
for(C1=1;C1<=Dim;C1++){
Sist[C2][C1]=Sist[C2][C1]-V1*Sist[Col][C1];
Inv[C2][C1]=Inv[C2][C1]-V1*Inv[Col][C1];}
}}

/*Aqui ya esta triangularizada, con 1s en diagonal, ahora se


diagonaliza*/
for(Col=Dim;Col>=1;Col--) for(C1=(Col-1);C1>=1;C1--)
{
V1=Sist[C1][Col];
for(C2=1;C2<=Dim;C2++){
Sist[C1][C2]=Sist[C1][C2]-V1*Sist[Col][C2];
Inv[C1][C2]=Inv[C1][C2]-V1*Inv[Col][C2];
}}
}

Código de”Leer.h”:

#include <stdio.h>
void Imprimir(char nombre[],char operacion[]);
void Imprimir2(char nombre[],char operacion[]);

void LeerResultados()
{
char Suma[] = "ResultadoSuma.txt";
char Sum[] = "suma";
char Resta[] = "ResultadoResta.txt";
char Res[] = "resta";
char Multiplica[] = "ResultadoMultiplica.txt";
char Mult[] = "multiplicacion";
char Transpuesta[] = "ResultadoTranspuesta.txt";
char Trans[] = "transpuesta";
Imprimir(Suma,Sum);
Imprimir(Resta,Res);
Imprimir(Multiplica,Mult);
Imprimir2(Transpuesta,Trans);
return;
}

void Imprimir(char nombre[],char operacion[])


{
FILE *fichero;
int i,j,numero;
fichero = fopen(nombre,"r");
if(fichero==NULL)
{
printf("Aun no se ha generado el archivo de resultado correspondiente\n");
}
else
{
printf("\n\t\tEl resultado de la %s de ambas Matices es:\n\n",operacion);
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
fscanf(fichero,"%d",&numero);
printf("\t %d",numero);
}
printf("\n");
}
}
fclose(fichero);
}

void Imprimir2(char nombre[],char operacion[])


{
FILE *fichero;
int i,j,numero;
fichero = fopen(nombre,"r");
if(fichero==NULL)
{
printf("Aun no se ha generado el archivo de resultado correspondiente\n");
}
else
{
printf("\n\t\tEl resultado de la %s de cada Matriz es:\n\n",operacion);
for(i=0;i<200;i++)
{

if(i==10||i==20||i==30||i==40||i==50||i==60||i==70||i==80||i==90||i==110|
|i==120||i==130||i==140||i==150||i==160||i==170||i==180||i==190)
{
printf("\n");
}
if(i==100)
{
printf("\n\n");
}
fscanf(fichero,"%d",&numero);
printf("\t %d",numero);
}
}
fclose(fichero);
}

Código de ”multiplicar.h”:

#include <stdio.h>
void MultiplicaMatriz(int A[10][10],int B[10][10])
{
int i,j,k,C[10][10];
FILE *fichero;
//OPERACION DE MULTIPLICACION
for (i=0;i<10;i++)
{
for (j=0;j<10;j++)
{
C[i][j]=0;
for (k=0;k<10;k++)
{
C[i][j]=C[i][j]+A[i][k]*B[k][j];
}
}
}
fichero = fopen("ResultadoMultiplica.txt","w");
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
fprintf(fichero,"%d\n",C[i][j]);
}
}
fclose(fichero);
printf("El resultado ha sido almacenado en el archivo ResultadoMultiplica\n");
return;
}

Código de ”resta.h”:

#include<stdio.h>

void RestaMatriz(int A[10][10],int B[10][10])


{
int i,j;
FILE *fichero;
fichero = fopen("ResultadoResta.txt","w");
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
fprintf(fichero,"%d\n",A[i][j]-B[i][j]);
}
}
fclose(fichero);
printf("El resultado ha sido almacenado en el archivo
ResultadoResta\n");
return;
}

Código de ”suma.h”:

#include<stdio.h>
void SumaMatriz(int A[10][10],int B[10][10])
{
int i,j;
FILE *fichero;
fichero = fopen("ResultadoSuma.txt","w");
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
fprintf(fichero,"%d\n",A[i][j]+B[i][j]);
}
}
fclose(fichero);
printf("El resultado ha sido almacenado en el archivo ResultadoSuma\n");
return;
}

Código de ”Transpuesta.h”:

#include<stdio.h>
void Matriz(int A[10][10],int k,int C[20][10]);

void TranspuestaMatriz(int A[10][10],int B[10][10])


{
int i,j,k=1;
int C[20][10];
FILE *fichero;
Matriz(A,k,C);
k++;
Matriz(B,k,C);
fichero = fopen("ResultadoTranspuesta.txt","w");
for(i=0;i<20;i++)
{
for(j=0;j<10;j++)
{
fprintf(fichero,"%d\n",C[i][j]);
}
}
fclose(fichero);
printf("El resultado ha sido almacenado en el archivo ResultadoTranspuesta\n");
return;
}

void Matriz(int A[10][10],int k,int C[20][10])


{
int i,j;
if(k==1)
{
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
C[i][j] = A[j][i];
}
}
}
else
{
for(i=10;i<20;i++)
{
for(j=0;j<10;j++)
{
C[i][j] = A[j][i-10];
}
}
}
}

Código de Junto.c:

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <strsafe.h>
#include "Suma.h"
#include "Resta.h"
#include "Multiplica.h"
#include "Transpuesta.h"
#include "Inversa.h"
#include "Leer.h"

#define MAX_THREADS 1
#define BUF_SIZE 255

int A[10][10]={
{8,5,6,4,1,8,2,7,3,3},
{7,5,5,3,3,2,3,1,2,9},
{3,5,4,2,2,1,4,7,6,7},
{2,4,5,8,7,1,2,6,5,4},
{8,8,1,2,7,5,1,5,5,1},
{5,6,7,5,6,4,2,4,9,5},
{6,4,9,8,6,2,5,6,5,3},
{3,5,6,2,8,4,3,4,8,1},
{1,7,2,4,8,4,9,5,6,3},
{6,1,4,5,8,8,8,5,7,4},
};
int B[10][10]={
{6,4,2,5,6,3,2,6,5,7},
{2,3,6,1,4,2,1,4,2,5},
{4,8,7,4,3,7,2,6,3,3},
{8,6,7,6,4,7,8,4,1,2},
{1,3,9,4,6,8,8,8,6,9},
{7,4,8,5,3,8,6,9,4,5},
{8,7,5,7,4,8,2,2,9,8},
{1,2,6,8,8,2,4,6,2,8},
{9,2,6,1,3,7,2,3,4,1},
{5,3,5,3,4,2,4,8,2,5},
};

DWORD WINAPI MyThreadFunction( LPVOID lpParam );


void ErrorHandler(LPTSTR lpszFunction);
int CreaHilos(int Z);

typedef struct MyData {


int val1;
int val2;
} MYDATA, *PMYDATA;

void main(){
STARTUPINFO si;
PROCESS_INFORMATION pi;
int i;
ZeroMemory(&si,sizeof(si));
si.cb=sizeof(si);
ZeroMemory(&pi,sizeof(pi));
do{
printf("Elija que Hilo quiere
realizar:\n1.SumaMatriz\n2.RestaMatriz\n3.MultiplicaMatriz\n4.Transpuesta
Matriz\n5.InversaMatriz\n6.VerResultados\n");
scanf("%d",&i);
switch(i){
case 1:
//Creacion del hilo
CreaHilos(1);
break;
case 2:
//Creacion del hilo
CreaHilos(2);
break;
case 3:
//Creacion del hilo
CreaHilos(3);
break;
case 4:
//Creacion del hilo
CreaHilos(4);
break;
case 5:
//Creacion del hilo
CreaHilos(5);
break;
case 6:
//Creacion del hilo
CreaHilos(6);
break;
default:
break;
}
}while(i!=6);

//Proceso Padre
printf("Soy el padre\n");
WaitForSingleObject(pi.hProcess,INFINITE);

//Terminacion controlada del proceso e hilo asociado de ejecucion


CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
void ErrorHandler(LPTSTR lpszFunction)
{

LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();

FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );

lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) lpszFunction) +
40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR) lpDisplayBuf, TEXT("Error"), MB_OK);

LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}

DWORD WINAPI MyThreadFunction( LPVOID lpParam )


{
HANDLE hStdout;
PMYDATA pDataArray;

TCHAR msgBuf[BUF_SIZE];
size_t cchStringSize;
DWORD dwChars;

hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if( hStdout == INVALID_HANDLE_VALUE )
return 1;

pDataArray = (PMYDATA)lpParam;

StringCchPrintf(msgBuf, BUF_SIZE, TEXT("\tSoy un Hilo\n"),


pDataArray->val1, pDataArray->val2);
StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);
WriteConsole(hStdout, msgBuf, (DWORD)cchStringSize, &dwChars, NULL);

return 0;
}

int CreaHilos(int Z)
{
PMYDATA pDataArray[MAX_THREADS];
DWORD dwThreadIdArray[MAX_THREADS];
HANDLE hThreadArray[MAX_THREADS];

int i;
for( i=0; i<MAX_THREADS; i++ )
{

pDataArray[i] = (PMYDATA) HeapAlloc(GetProcessHeap(),


HEAP_ZERO_MEMORY,
sizeof(MYDATA));

if( pDataArray[i] == NULL )


{
ExitProcess(2);
}

pDataArray[i]->val1 = i;
pDataArray[i]->val2 = i+100;

hThreadArray[i] = CreateThread(
NULL, // default security attributes
0, // use default stack size
MyThreadFunction, // thread function name
pDataArray[i], // argument to thread function
0, // use default creation flags
&dwThreadIdArray[i]); // returns the thread identifier

if (hThreadArray[i] == NULL)
{
ErrorHandler(TEXT("CreateThread"));
ExitProcess(3);
}
//Se realiza la operacion que se escojio
if(Z==1){
SumaMatriz(A,B);
}
if(Z==2){
RestaMatriz(A,B);
}
if(Z==3){
MultiplicaMatriz(A,B);
}
if(Z==4){
TranspuestaMatriz(A,B);
}
if(Z==5){
InversaMatriz();
}
if(Z==6){
LeerResultados();
}
}

WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);

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


{
CloseHandle(hThreadArray[i]);
if(pDataArray[i] != NULL)
{
HeapFree(GetProcessHeap(), 0, pDataArray[i]);
pDataArray[i] = NULL; // Ensure address is not reused.
}
}

return 0;
}

Pantalla de Salida:

*Nota: Las matrices ya están propuestas en el código

Suma de Matriz:

Resta de matriz:
Multiplicación de Matrices:

Transpuesta de matrices:

Observaciones:

Aquí pudimos observar al momento de ejecutarlo en dev c++ que este programa se ejecuta más
rápido que el que se hizo en la practica 4 con puros procesos y esto porque como es un programa
que ejecuta ciertas funciones del código de forma concurrente, el procesamiento o resultado que
nos arroja es mucho más rápido que el de la creación de procesos que es mas de manera
secuencial.
7. Programe una aplicación (tanto en Linux como en Windows) que copie los archivos y directorios
contenidos dentro de una ruta específica. Por cada directorio que se encuentre al momento de
copiar, se deberá de crear un hilo que se encargará de copiar los archivos existentes en ese
directorio. Nuevamente, si se encuentra otro directorio se creará otro hilo, así sucesivamente.
Todos los hilos deberán de correr concurrentemente. Las rutas de origen y destino se aceptarán
por línea de comando.

Código:

#include <windows.h>
#include <stdio.h>
#include <dirent.h>

void CopiarArchivos(char *origen, char *destino);


void CopiarDirectorio(char *origen, char *destino);
DWORD WINAPI FuncionHilo(LPVOID IpParam);

typedef struct informacion info;


struct informacion{
char origen[100];
char destino[100];
};

//Funcion que crea directorios que contengan archivos


void CopiarDirectorio(char *origen, char *destino){
int copias, tamano, tamano2;
char mdireccion[100];
char directorio[100];
char destino_del_destino[300];
char origen_del_origen[300];
strcpy(mdireccion, destino);
strcat(mdireccion, "\\");
//Numero de Directorios que quieren ser creados
printf("\nCuantos directorios vas a copiar: ");
scanf("%d", &copias);
for(int i = 0;i < copias; i++){
//Establece el directorio de trabajo
printf("Introduzca la ruta del directorio secundario\n\n");
scanf("%s", &origen_del_origen);
//Creacion de directorio
printf("\nnombre del directorio: ");
scanf("%s", directorio);
strcat(destino, "\\");
strcat(destino, directorio);
mkdir(destino);
//Se ingresan archivos a los directorios
tamano = strlen(destino);
tamano2 = strlen(origen_del_origen);
CopiarArchivos(origen_del_origen, destino);
//CopiarArchivos(origen, destino);
CopiarDirectorio(origen, destino);
printf(" --> Se guardaron datos en directorio \n");
printf("----------------------------------------------------\n");
tamano = strlen(destino);
memset(destino, 0, tamano);
strcpy(destino, mdireccion);
memset(origen_del_origen, 0, tamano2);
}
}

//Funcion que crea el hilo para copiar un determinado numero de archivos


void CopiarArchivos(char *origen, char *destino){
DWORD Idhilo;
HANDLE manHilo;
info argumentos;
int copias;
//Numero de archivos que quieren ser copiados
printf("\nCuantos archivos vas a copiar: ");
scanf("%d", &copias);
//Se guarda el origen del directorio en la estructura
strcpy(argumentos.origen, origen);
//Se guarda el origen del directorio en la estructura
strcpy(argumentos.destino, destino);
for(int i = 0; i < copias; i++){
//Creacion del hilo para copiar archivos
manHilo = CreateThread(NULL, 0, FuncionHilo, &argumentos, 0, &Idhilo);
//Espera para la finalizacion del hilo creado
WaitForSingleObject(manHilo, INFINITE);
//Cierre del manejador del hilo creado
CloseHandle(manHilo);
}
}

//Funcion que copia un archivo a un directorio


DWORD WINAPI FuncionHilo(LPVOID IpParam){
info *datos = (info*)IpParam;
//int copias;
char nombre[50];
char aux[50];
char name[] = "Copia_";
SetCurrentDirectory(datos -> origen);
CreateDirectory (datos -> destino, NULL);
strcat(datos -> destino, "\\");
strcpy(aux, name);
strcpy(name, aux);
strcpy(datos -> origen, datos -> destino);
printf("\nnombre del archivo a copiar: ");
scanf("%s", &nombre);
CopyFile(nombre, strcat(name, nombre), TRUE );
strcat(datos -> origen, name);
//Establecer el directorio de los archivos a ser copiados
if(0 != MoveFileEx(name, datos -> origen, MOVEFILE_COPY_ALLOWED)){
printf(" --> Se copio con exito\n");
}
else{
printf("ERROR %d\n", GetLastError());
}
}

int main(){
system("cls");
char direccion[100];
char ndireccion[100];
//Establece el directorio de trabajo
printf("Introduzca la ruta del directorio de los archivos\n\n");
scanf("%s", &direccion);

//Creacion de directorio
printf("\nIntroduzca la ruta del nuevo directorio de almacenamiento\n\n");
scanf("%s", &ndireccion);

CopiarArchivos(direccion, ndireccion);
printf("---------------------------------------------------------");
CopiarDirectorio(direccion, ndireccion);
}

Pantalla de Salida:

Ingresamos los datos de las rutas Origen y destino para poder copiar los archivos.

Origen

destino

Después ingresamos los archivos que queremos copiar al nuevo directorio de almacenamiento
Se ingresan los archivos a copiar

Se copian los archivos en el


nuevo directorio

Después ingresamos los directorio que están contenidos en la carpeta origen el cual solo es “1”

Se ingresa la dirección del


directorio, para que se copien los
archivos en el nuevo directorio
creado.

Directorio
creado

Cuando estemos en el directorio se copian los archivos contenidos en el directorio del directorio.
Se copian los archivos en
el nuevo directorio

Como el directorio origen tiene otro directorio lo copiamos en el directorio destino.

Se ingresa la dirección del


directorio, para que se copien los
archivos en el nuevo directorio
creado.

Directorio
creado

Por ultimo copiamos el último archivo contenido en el directorio.


Se copian los
últimos archivos

You might also like