VI UNIDAD C++BUILDER MULTIPROCESAMIENTO

TEMA 2 OBJETOS CONCURRENTES C++BUILDER


La buena noticia, C++Builder ya trae incorporado un objeto de tipo concurrente llamado Thread object, que pertenece a la clase TThread ( ver en ayuda sus propiedades y métodos)

Se analiza el objeto Thread en su perspectiva mas simple y se anexan comentarios para su comprensión:

Procedimiento:

1.- File, Close All

2.- File, New, Thread Object class name = proceso1

3.- File, Save As

- abrir folder tarea1

- proceso1

4.- Click derecho en donde dice #include “proceso1.h” y open source/header, para tener a la vista los dos archivos normales de un componente proceso1.cpp y proceso1.h

* Observar que este objeto, crea una clase llamada proceso1 derivada de la clase Thread.

* Esto también significa que en proceso1.h se almacena la declaración o definición de la nueva clase proceso1 y que en el archivo proceso1.cpp se almacenara la implementación de los métodos que contenga la clase proceso1, tal como se analizo en la

UNIDAD de componentes.

5.- El Código de proceso1.h es;

//----------------------------------------------------------
#ifndef proceso1H
#define proceso1H
//----------------------------------------------------------
#include <vcl\Classes.hpp>
//----------------------------------------------------------
class proceso1 : public TThread
{
prívate:
protected:
void __fastcall Execute();
public:
__fastcall proceso1(bool CreateSuspended);
};
//----------------------------------------------------------
#endif

* Una clase proceso1 descendiente de la clase TThread, no hay sorpresas aquí.

* Un método protegido llamado Execute(), este método es muy importante porque cuando se crea una instancia de la clase proceso1, todo el código que contiene es ejecutado automáticamente, en otras palabras, es dentro de este método donde se coloca el código del proceso ( en el archivo de implementación).

* El constructor proceso1, lleva como parámetro una variable booleana es decir con valor true o valor false.

* Además el propio constructor como se observa en el código crea el proceso, pero el hilo lo tiene suspendido, en cuanto se active o continúe el proceso, este constructor llama o activa el método Execute().

6.- El código de proceso1.cpp es:

//----------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
#include "proceso1.h"
//----------------------------------------------------------
// Important: Methods and properties of objects in VCL can
// only be used in a method called using Synchronize, for // // example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall proceso1::UpdateCaption()
// {
// Form1->Caption = "Updated in a thread";
// }
//----------------------------------------------------------
__fastcall proceso1::proceso1(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
//----------------------------------------------------------
void __fastcall proceso1::Execute()
{
//---- Place thread code here ----
}
//---------------------------------------------------------

* No hay muchas sorpresas, solo la implementación de los dos métodos que contiene la clase:

1.- El constructor proceso1, con su parámetro

2.- El método Execute() que deberá contener el código del proceso y que se activara cuando se resuma o se pida que se continúe el proceso.

* Pero si existen unos comentarios o recomendaciones muy importantes que siempre deberán tenerse en cuenta.

El resumen de la recomendación es que nunca se deberá poner dentro del código del método Execute(), ninguna instrucción que referencie directamente un componente de VCL, incluyendo Form1 o cualquier componente visual.

* Si el Método Execute(), necesita procesar cualquier elemento o componente visual, deberá hacer una llamada a un segundo método que si podrá manipular directamente la forma o el componente necesitado, y además la llamada de Execute() al segundo método, deberá ser dentro de un método especial de Execute(), llamado Synchronize(segundo método).

* El ejemplo que se da en el comentario, es que se pretende que dentro de un proceso concurrente o hilo, se actualice el Caption de Form1, recordando lo anterior, ese actualización no puede hacerse directamente dentro del método Execute(), en su lugar Execute(), hace un llamado a otro método(UpdateCaption) de la clase, para que este ultimo método lo actualice.

Se construye el primer programa concurrente, usando el ejemplo que esta en el comentario.

Procedimiento:

1.- Crear el Thread Object, grabarlo como se indico, y cargar a la vista los dos archivos, proceso1.h y proceso1.cpp

2.- Modificar los códigos con las siguientes instrucciones:

2.1.- proceso1.h

//----------------------------------------------------------
#ifndef proceso1H
#define proceso1H
//----------------------------------------------------------
#include <vcl\Classes.hpp>
//----------------------------------------------------------
class proceso1 : public TThread
{
prívate:
protected:
void __fastcall UpdateCaption();
void __fastcall Execute();
public:
__fastcall proceso1(bool CreateSuspended);
};
//----------------------------------------------------------
#endif

* Observar que como se ocupa un segundo método especializado, en accesar componentes visuales, se tiene que declarar dentro de la clase, ya sea en su parte protegida o en su parte publica.

2.2.- proceso1.cpp

//----------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
#include "proceso1.h"
//----------------------------------------------------------
// Important: Methods and properties of objects in VCL can // only be
used in a method called using Synchronize, for // example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall proceso1::UpdateCaption()
// {
// Form1->Caption = "Updated in a thread";
// }
//----------------------------------------------------------
__fastcall proceso1::proceso1(bool CreateSuspended)
: TThread(CreateSuspended)
{ }
//----------------------------------------------------------
void __fastcall proceso1::Execute()
{
//---- Place thread code here ----
Synchronize(UpdateCaption);
}
//----------------------------------------------------------
void __fastcall proceso1::UpdateCaption()
{
Form1->Caption = "Updated in a thread";
}

* Observar que Execute(), en este caso solo llama a un segundo método(), usando su método especial.

* El segundo método, es un caso normal, se declaro en el archivo proceso1.h y se construyo o implemento al final del archivo proceso1.cpp

* Grabar los dos archivos con File, Save All o CTRL S con cada uno, ya grabados en folder tarea1, usar File, Close All

La preguntas son:

1.- Como se incorpora este objeto concurrente a una aplicación

2.- Como se activa o se continua la ejecución del proceso concurrente.

R.- esperar a la tercera edición del libro :>)

Procedimiento:

1.- Crear y almacenar el objeto thread, llamado proceso1 con el procedimiento anterior, asegurarse de que ya todo este CLOSE All y los archivos en folder tarea1.

2.- File, New Aplication

3.- File, Save Project as, y asegurarse que se grabe dentro del folder tarea1

4.- Poner un BUTTON OK y solo se escriben los siguientes tres renglones de código:

#include "proceso1.cpp"
proceso1 *pro1;
pro1 = new proceso1(false);

* observar dentro de Unit1, donde va cada uno de ellos;

4.1.- Unit1.cpp

//----------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
#include "Unit1.h"
//----------------------------------------------------------
#pragma resource "*.dfm"
TForm1 *Form1;
#include "proceso1.cpp"
//----------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//----------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
proceso1 *pro1;
pro1 = new proceso1(false);
}
//----------------------------------------------------------

* #include “proceso1.cpp”, es para que Form1 o sus componentes, puedan accesar proceso1.

* proceso1 *pro1; crea un variable de tipo proceso1 llamada pro1 derivada o instancia de la clase proceso1

* pro1 = New proceso1(false); crea físicamente o en memoria el objeto, llamando a su constructor.

* false.- Recordar que el constructor crea el objeto concurrente pero suspendido, es decir en proceso1, CreateSuspend = true(default), por esa razón en la llamada al constructor se le informa que CreateSuspend = false, por tanto el proceso se reactiva y hace la llamada al método Execute().

* Como se observa, no es necesario ni tampoco se puede llamar directamente al método Execute(), es decir no es valido pro1→Execute(); pero si es valido

pro1→Resume(), pro1→Suspend(), pro1→Terminate(), etc., ver la ayuda de la clase TThread.

La pantalla de salida es:

image120.jpg

Politica de Privacidad