How do you convert one "serial" program to parallel programming?.In this article try to show a didactical example for this convertion.The example program was made on the paradigm object oriented programming ( OOP ) using c++.
The program on OOP "serial"
On the first class of programming logic at University Autonomous of Guadalajara[1] ( UAG ) this example is used. Make a program on Ms Windows using its real mode[2] that show an asterisk bouncing on diagonal shape on the screen ( when crash with the borders ). The end is when is pressed any key.
**********************
asterisco.h
**********************
#include
class Asterisco
{
public:
Asterisco();
int getCol();
int getRen();
void setCol( int valor );
void setRen( int valor );
void mostrar();
int getSentido();
void setSentido( int valor );
void iniciar();
void mover();
private:
int col;
int ren;
char simbolo;
int sentido;
void borrar();
};
**********************
asterisco.cpp
**********************
#include
#include
#include
#include "asterisco.h"
Asterisco::Asterisco()
{
simbolo='*';
sentido=0;
}
int Asterisco::getCol()
{
return col;
}
int Asterisco::getSentido()
{
return sentido;
}
int Asterisco::getRen()
{
return ren;
}
void Asterisco::setCol( int valor )
{
col= valor;
}
void Asterisco::setSentido( int valor )
{
sentido=valor;
}
void Asterisco::setRen( int valor )
{
ren= valor;
}
void Asterisco::mostrar()
{
gotoxy( getCol(), getRen() );
printf("%c", simbolo, ren );
}
void Asterisco::borrar()
{
gotoxy( getCol(), getRen() );
printf(" " );
}
void Asterisco::mover()
{
borrar();
switch ( sentido )
{
case 0: //rigth upper
if ( ren>1)
{
if (col < 79 )
{
ren-=1;
col+=1;
}
else
sentido= 1;
}
else
sentido=2;
break;
case 1: //left upper
if ( ren>1 )
{
if ( col>1 )
{
ren-=1;
col-=1;
}
else
sentido= 0;
}
else
sentido= 3;
break;
case 2: //right down
if ( ren<24 )
{
if ( col< 80 )
{
ren+=1;
col+=1;
}
else
sentido= 3;
}
else
sentido= 0;
break;
case 3: //left down
if ( ren< 24 )
{
if ( col > 1 )
{
ren+=1;
col-=1;
}
else
sentido= 2;
}
else
sentido= 1;
break;
}
mostrar();
}
**********************
inicio.cpp
**********************
#include
#include
#include "asterisco.h"
void main()
{
Asterisco *obj= new Asterisco();
clrscr();
obj->setCol( 20 );
obj->setRen( 18 );
obj->setSentido( 0 );
obj->mostrar();
do
{
Sleep( 200 );
obj->mover();
} while ( !kbhit() );
}
For compiling the program using the free compiler of Borland version 5.5[3] :
bcc32 asterisco.cpp inicio.cpp
The program on OOP "parallel
After this exercise, the teacher ask for one modification on the program: Show many asterisks independents bouncing at the screen maybe on differents directions. The program use the function random for initial position and direction. The response could be an objects array and with iterations move each object one position. In this case the user believe that all asterisks are moving on the same time.This is the code:
********************
asterisco.h
********************
#include < windows.h >
class Asterisco
{
public:
Asterisco();
int getCol();
int getRen();
void setCol( int valor );
void setRen( int valor );
void mostrar();
int getSentido();
void setSentido( int valor );
int getTermino();
void setTermino( int valor );
void mover();
private:
int col;
int ren;
char simbolo;
int sentido;
char termino;
void borrar();
};
********************
asterisco.cpp
********************
#include < stdio.h >
#include < conio.h >
#include < windows.h >
#include "asterisco.h"
Asterisco::Asterisco()
{
simbolo='*';
sentido=0;
termino='a';
}
int Asterisco::getCol()
{
return col;
}
int Asterisco::getSentido()
{
return sentido;
}
int Asterisco::getRen()
{
return ren;
}
void Asterisco::setCol( int valor )
{
col= valor;
}
void Asterisco::setSentido( int valor )
{
sentido=valor;
}
void Asterisco::setRen( int valor )
{
ren= valor;
}
void Asterisco::mostrar()
{
gotoxy( getCol(), getRen() );
printf("%c", simbolo, ren );
}
void Asterisco::borrar()
{
gotoxy( getCol(), getRen() );
printf(" " );
}
void Asterisco::mover()
{
borrar();
switch ( sentido )
{
case 0: //rigth upper
if ( ren>1)
{
if (col < 79 )
{
ren-=1;
col+=1;
}
else
sentido= 1;
}
else
sentido=2;
break;
case 1: //left upper
if ( ren>1 )
{
if ( col>1 )
{
ren-=1;
col-=1;
}
else
sentido= 0;
}
else
sentido= 3;
break;
case 2: //right down
if ( ren<24 )
{
if ( col< 80 )
{
ren+=1;
col+=1;
}
else
sentido= 3;
}
else
sentido= 0;
break;
case 3: //left down
if ( ren< 24 )
{
if ( col > 1 )
{
ren+=1;
col-=1;
}
else
sentido= 2;
}
else
sentido= 1;
break;
}
mostrar();
}
int Asterisco::getTermino()
{
return termino;
}
void Asterisco::setTermino( int valor )
{
termino= valor;
}
********************
inicio.cpp
********************
#include
#include
#include
#include
#include "asterisco.h"
const int CANTIDAD_ASTERISCOS= 3;
void main()
{
Asterisco *obj[ CANTIDAD_ASTERISCOS ];
int i;
clrscr();
randomize();
for(i=0; i
obj[i]= new Asterisco();
obj[i]->setCol( random( 80 ) );
obj[i]->setRen( random( 24 ) );
obj[i]->setSentido( random( 4 ) );
obj[i]->mostrar();
}
i=0;
do
{
Sleep( 250);
obj[i++]->mover();
i= ( i>= CANTIDAD_ASTERISCOS ? 0 : i );
} while ( !kbhit() );
}
The change was made in the main. On this moment is very easy and simple introducing the parallel programming using one thread for each asterisk and there are few changes.
********************
asterisco.h
********************
#include
class Asterisco
{
public:
Asterisco();
int getCol();
int getRen();
void setCol( int valor );
void setRen( int valor );
void mostrar();
int getSentido();
void setSentido( int valor );
void iniciar(); //new method
int getTermino();
void setTermino( int valor );
private:
int col;
int ren;
char simbolo;
int sentido;
char termino;
void borrar();
void mover(); //now is privated
};
********************
asterisco.cpp
********************
#include
#include
#include
#include "asterisco.h"
Asterisco::Asterisco()
{
simbolo='*';
sentido=0;
termino='p';
}
int Asterisco::getCol()
{
return col;
}
int Asterisco::getSentido()
{
return sentido;
}
int Asterisco::getRen()
{
return ren;
}
void Asterisco::setCol( int valor )
{
col= valor;
}
void Asterisco::setSentido( int valor )
{
sentido=valor;
}
void Asterisco::setRen( int valor )
{
ren= valor;
}
void Asterisco::mostrar()
{
gotoxy( getCol(), getRen() );
printf("%c", simbolo );
}
void Asterisco::borrar()
{
gotoxy( getCol(), getRen() );
printf(" " );
}
void Asterisco::iniciar() //has the code that was used on main
{
termino='a';
do
{
Sleep( 200 );
mover();
} while ( !kbhit() );
termino='f';
}
void Asterisco::mover()
{
borrar();
switch ( sentido )
{
case 0: //rigth upper
if ( ren > 1)
{
if (col < 79 )
{
ren-=1;
col+=1;
}
else
sentido= 1;
}
else
sentido=2;
break;
case 1: //left upper
if ( ren > 1 )
{
if ( col > 1 )
{
ren-=1;
col-=1;
}
else
sentido= 0;
}
else
sentido= 3;
break;
case 2: //rigth down
if ( ren < 24 )
{
if ( col < 80 )
{
ren+=1;
col+=1;
}
else
sentido= 3;
}
else
sentido= 0;
break;
case 3: //left down
if ( ren < 24 )
{
if ( col > 1 )
{
ren+=1;
col-=1;
}
else
sentido= 2;
}
else
sentido= 1;
break;
}
mostrar();
}
int Asterisco::getTermino()
{
return termino;
}
void Asterisco::setTermino( int valor )
{
termino= valor;
}
********************
inicio.cpp
********************
#include
#include
#include
#include "asterisco.h"
#include
DWORD WINAPI iniciarAsterisco(LPVOID param);
const int CANTIDAD_HILOS = 3;
Asterisco *obj[ CANTIDAD_HILOS ];
void main()
{
HANDLE hilos[ CANTIDAD_HILOS ];
int i;
int *valorEntero;
void *parametroVoid= NULL;
randomize();
clrscr();
for( i=0; i < CANTIDAD_HILOS ;i += 1 )
{
obj[ i ] = new Asterisco();
obj[ i ] -> setCol( random(80) );
obj[ i ] -> setRen( random(24) );
obj[ i ] -> setSentido( random(5) );
obj[ i ] -> mostrar();
}
parametroVoid= malloc( sizeof(int ) );
valorEntero= (int *) parametroVoid;
for( i=0; i< CANTIDAD_HILOS ;i += 1 )
{
*valorEntero= i;
if ( ( hilos[i]= CreateThread( NULL, 0, iniciarAsterisco, parametroVoid, 0, NULL )) == NULL )
printf("error en hilo 0");
Sleep( 500 );
}
WaitForMultipleObjects( CANTIDAD_HILOS, hilos, true, INFINITE );
}
DWORD WINAPI iniciarAsterisco(LPVOID param)
{
int *i= (int *) param;
obj[ (*i) ]->iniciar();
return 0;
}
Note: Some times the screen showed more asterisk by memory errors.
The instruction CreateThread is studied on many coursewares, in this article don't try to explain it.
Future improvements
Graphic user interface.
Don't use the function Sleep for stop the principal flow between each definition thread.
References
[1] Universidad Autónoma de Guadalajara. http://www.uag.mx
[2] Real Mode of Ms Windows. Wikipedia. http://en.wikipedia.org/wiki/Real_mode
[3] Borland C++ Compiler version 5.5 Free Download. Embarcadero developer network. http://edn.embarcadero.com/article/20633
No hay comentarios:
Publicar un comentario
Are you ready?