[Jderobot] problema con C++

Oscar Garcia oscar.robotica en linaresdigital.com
Mar Jul 29 21:55:05 CEST 2014


El 29/07/14 a las #4, Laura Martín Ramírez escribió:
> /struct item{
>     std::string name;
>     bool isActivate;
> };/
>
> Y el array lo declaro así:
>
> /struct item items[100];/


Bien, una estructura estática.


> Todo esto lo pongo dentro de la clase que creo, es decir después de :
>
> #include <Ice/Ice.h>
> #include <IceUtil/IceUtil.h>
> #include <gtkmm.h>
> class Application : public Gtk::Window {


Entonces es una propiedad (variable) privada de la clase.


> Dentro de esta clase tengo unos hilos de ejecución. Y quiero modificar 
> los valores de item de una posición del array por ejemplo:
>
> /items[0].name = "prueba";
> items[0].isActivate =1;/


Según parece quieres solucionar problemas de concurrencia.

El primer problema que veo es que no has declarado el array como 
volátil, por lo que el compilador podría realizar optimizaciones sobre 
el uso de la variable que podrían provocar casos indeseados 
(optimizaciones en bucles sobre todo).

Tendrías que declararlo como:


/volatile struct item items[100];/


Por otro lado, ya que estás usando C++, deberías plantearte usar clases 
en vez de estructuras, así podrás hacer uso de herramientas de 
tratamiento de listas, colas, etc más avanzadas que en C sin tener que 
controlar la memoria que se reserva, etc.

http://www.cplusplus.com/reference/array/array/
http://www.cplusplus.com/reference/list/list/



> Al modificarlos desde dentro de un hilo no se guarda en los valores 
> del array.


Esto es lo que no entiendo... ¿qué quieres decir con que no se guardan 
los valores del array?

Si tienes en un bucle que se muestre el contenido de una variable o 
posición, sin el uso del modificador "volatile" no funcionará debido a 
las optimizaciones del compilador:

while (true) {
       std::cout << items[0].name << std::endl;
       IceUtil::ThreadControl::sleep(IceUtil::Time::seconds(1)); /* 
asumo que usas ICE */
}

Ese bucle anterior probablemente acabará siendo una única obtención del 
valor previo al bucle (la resolución del valor se realiza accediendo a 
la posición deseada del array y moviendo el contenido de name a alguna 
posición temporal de la pila) y posteriormente, como no hay ninguna 
modificación del array en el interior del bucle, posiblemente no se 
actualice ese valor temporal de la pila nunca más.

Aunque pensemos que debería accederse a esa información y refrescarse en 
cada iteración del bucle puede que no sea así si no usamos, como dije 
antes, el modificador "volatile".


> Lo que hago es desde un hilo modificar los valores como acabo de 
> escribir y desde otro lo imprimo, pero me sale el valor al que se ha 
> inicializado el array.
>
> void* change ( void* ) {
>       std::cout << items[i].name << std::endl;
> }
>
> Espero haberme explicado bien.


Ese código no lo entiendo bien. ¿Para qué tiene void* como salida si no 
haces un return? ¿Para qué tienes un parámetro void* si no lo usas?

Quizá querías decir "void change(void) {" o simplemente "void change() {".

Resumiendo:
a) Debes hacer uso del modificador "volatile" para evitar que el 
compilador realice optimizaciones en propiedades de clase que son 
cambiadas por otras hebras, incluso aunque estemos usando semáforos para 
controlar la concurrencia hemos de evitar dichas optimizaciones.
b) Debes usar mecanismos para controlar la concurrencia (acceso de 
lectura y/o modificación) a los datos de ese array estático.

Para ese último punto te aconsejo usar las herramientas que te ofrece 
ICE para esa tarea:
http://doc.zeroc.com/pages/viewpage.action?pageId=5048344


Tu código quedaría:

/IceUtil::Mutex _datosMutex;
volatile struct item items[100];
[...]
while (true) {/
////_datosMutex.lock();//
/////      /* Podemos leer datos de la estructura de manera segura */
//// std::cout << items[0].name << std::endl;
//////_datosMutex.unlock();///
/////////// ///* la espera debe realizarse FUERA de la zona de exclusión 
mutua */
       IceUtil::ThreadControl::sleep(IceUtil::Time::seconds(1)); /* 
asumo que usas ICE */
}
[...]
////_datosMutex.lock();//
//////* Podemos modificar los datos de la estructura de manera segura */
/////items[0].name = "prueba";
items[0].isActivate =1;
/////_datosMutex.unlock();///
///[...]
//

> Muchas gracias,
> Laura M.

Espero que te sea de utilidad.
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: http://gsyc.escet.urjc.es/pipermail/jde-developers/attachments/20140729/9e78e00b/attachment.htm 
------------ próxima parte ------------
Se ha borrado un mensaje que no está en formato texto plano...
Nombre     : smime.p7s
Tipo       : application/pkcs7-signature
Tamaño     : 2245 bytes
Descripción: Firma criptográfica S/MIME
Url        : http://gsyc.escet.urjc.es/pipermail/jde-developers/attachments/20140729/9e78e00b/attachment.bin 


More information about the Jde-developers mailing list