Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Pthread tipo c -> c++

Estas en el tema de Pthread tipo c -> c++ en el foro de C/C++ en Foros del Web. Hola de nuevo...continuando con el tema de los pthreads traigo una duda desde hace tiempo, la cual es como puedo hacer que un pthread del ...
  #1 (permalink)  
Antiguo 20/05/2013, 08:03
 
Fecha de Ingreso: mayo-2011
Mensajes: 49
Antigüedad: 13 años, 6 meses
Puntos: 0
Pthread tipo c -> c++

Hola de nuevo...continuando con el tema de los pthreads traigo una duda desde hace tiempo, la cual es como puedo hacer que un pthread del tipo void *cliente_hilo( void *host1 ); sea miembro de una clase. Esto lo necesito porque conozco mas de C que de C++ por lo cual en mis programas que desarrollo con wxwidgets junto con codeblocks uso C++ únicamente para el ambiente grafico el formulario las cajas de texto, los combos pero la parte funcional generalmente está hecha en C normal pero he encontrado algunas dificultades al no poder hacer mi función phtread miembro del formulario principal ...problemas que he solucionado usando variables globales para comunicarme con los objetos contenidos en el formulario .pero es muy tedioso motivo por el cual hago esta pregunta..
Al declarar la funcion dentro de la calse formulario principal de esta manera

class mioFrame: public wxFrame
{
public:

mioFrame(wxWindow* parent,wxWindowID id = -1);
virtual ~mioFrame();
void *cliente_hilo( void *host1 );
......
}
Obtengo el siguiente error..

error: argument of type 'void* (mioFrame::)(void*)' does not match 'void* (*)(void*)'|

Al invocarla de esta manera.

pt=pthread_create(&hilo, NULL,cliente_hilo, host11);

Aclaro que la función anterior trabaja perfectamente al declararla fuera de la clase.
Sé que wxwidgets tiene clases pthread que pienso aprender a manejar pero de momento necesito una solución más cercana ya que el programa funciona, solo que no me parece "elegante" la manera como lo hago trabajar al no poder declarar la función hilo dentro de la clase principal.
  #2 (permalink)  
Antiguo 20/05/2013, 08:59
 
Fecha de Ingreso: julio-2012
Mensajes: 375
Antigüedad: 12 años, 4 meses
Puntos: 28
Respuesta: Pthread tipo c -> c++

Tienes dos soluciones:

- Sacar la función fuera de la clase.
- Usar el operador de ambito '::' para acceder a un miembro estático de la clase:

Código C++:
Ver original
  1. pt=pthread_create(&hilo, NULL,mioFrame::cliente_hilo, host11);

Ojo, para que funcione tienes que declarar el void* como static void*... Personalmente considero que es mejor la primera opción (puedes pasarle la dirreción de tu clase como parametro (this) y de ahí acceder al resto de variables).
  #3 (permalink)  
Antiguo 20/05/2013, 20:02
 
Fecha de Ingreso: mayo-2011
Mensajes: 49
Antigüedad: 13 años, 6 meses
Puntos: 0
Respuesta: Pthread tipo c -> c++

hola de nuevo amchacon gracias por la respuesta pero como ya comente no soy muy bueno con el c++ y debo admitir que nunca he usado el famoso puntero this.

si mal no entendí de su respuesta ,propone como solución pasar como parámetro al pthread el operador this del formulario principal..pero no lo he podido hacer.pego la estructura usada en mi código

typedef struct {
int id; //identificador del thread
int pos;
char* cadena;
struct sockaddr_in conectado;
// this->??????????????? aqui esta mi duda

} mi_tipo;
mi_tipo mensaje;


espero tener otra pequeña ayuda para construir correctamente la estructura.
  #4 (permalink)  
Antiguo 21/05/2013, 00:50
 
Fecha de Ingreso: julio-2012
Mensajes: 375
Antigüedad: 12 años, 4 meses
Puntos: 28
Respuesta: Pthread tipo c -> c++

No no, no puedes poner un this en una definición. La estructura sería la siguiente:

Código C:
Ver original
  1. typedef struct {
  2. int id; //identificador del thread
  3. int pos;
  4. char* cadena;
  5. struct sockaddr_in conectado;
  6.  
  7. mioFrame* Clase; // Defino un puntero a mioFrame;
  8.  
  9. } mi_tipo;
  10. mi_tipo mensaje;
  11.  
  12. mensaje.id = IdThread; // Rellenamos la estructura
  13. //...
  14. Clase = this; // Solo puedes usar el puntero this dentro de la clase

Una vez en el thread, puedes actuar como si de una estructura se tratase:

Código C:
Ver original
  1. void* Hilo(void* parametro)
  2. {
  3.   //...
  4.   parametro->Clase->Numero // accediendo a la variable "Numero" de la clase (nota, la variable debe ser publica).
  5. }

Una buena práctica es, si no necesitas modificar la variable, declarala como privada y crear un método get():

Código C++:
Ver original
  1. class miFrame
  2. {
  3. private:
  4.   int MiVariable;
  5.  
  6. public:
  7.    int getMiVariable() { return MiVariable;}
  8. };

Es una manera elegante de hacer un acceso de solo lectura:

Código C:
Ver original
  1. void* Hilo(void* parametro)
  2. {
  3.   //...
  4.   parametro->Clase->getNumero(); // accediendo a la variable "Numero" de la clase (nota, la variable debe ser publica).
  5. }

Es una de las mayores ventajas de C++: El encapsulamiento, te impide que cometas errores.
  #5 (permalink)  
Antiguo 22/05/2013, 09:02
 
Fecha de Ingreso: mayo-2011
Mensajes: 49
Antigüedad: 13 años, 6 meses
Puntos: 0
Respuesta: Pthread tipo c -> c++

Muchas gracias amchacon debido a su respuesta ya puedo comunicarme con el formulario principal de mi programa y sin su ayuda me hubiera costado bastante trabajo lograrlo....

lo que hice fue algo muy similar a su ultima respuesta publicada ,solo que en ves de crear un función publica para leer la hice para escribir una caja de texto..no se si eso pueda causar algún problema.

pero al ver funcionando la comunicación pthread -> clase me surgió otra duda que publico aquí mismo.

yo vengo de programar microntroladores por eso es que de c++ solo conozco lo mas básico y tenia alguna experiencia en visual basic pero para este ultimo no hay que conocer mucho de POO para usarlo .y tengo un concepto de las interrupciones o eventos que no se si aplican tambien al c++ de pc. y es que si en medio del código que atiende una interrupción se presenta otro evento del mismo tipo este debe quedar en cola y sera atendido cuando se finalice la rutina de servicio.

esto lo pregunto por que los pthreads que creo se ejecutan de manera "paralela" por lo que me surge la pregunta de que ocurre si dos o mas pthread acceden la caja de texto y quieren escribi "Aqui estoy".

podría ocurrir que se escribiese aqui astaquioy estoy"...o no deberia ocurrir este tipo de problemas?..por lo que comente en el párrafo anterior.
  #6 (permalink)  
Antiguo 22/05/2013, 12:08
 
Fecha de Ingreso: julio-2012
Mensajes: 375
Antigüedad: 12 años, 4 meses
Puntos: 28
Respuesta: Pthread tipo c -> c++

Cita:
yo vengo de programar microntroladores por eso es que de c++ solo conozco lo mas básico y tenia alguna experiencia en visual basic pero para este ultimo no hay que conocer mucho de POO para usarlo .y tengo un concepto de las interrupciones o eventos que no se si aplican tambien al c++ de pc. y es que si en medio del código que atiende una interrupción se presenta otro evento del mismo tipo este debe quedar en cola y sera atendido cuando se finalice la rutina de servicio.
C++ no incluye ninguna rutina de multihilo, por lo que no hay ningun sistema de interrupciones/eventos detrás. La programación multihilo es controlada por librerías externas (en este caso pthread). Normalmente escrita por el propio sistema operativo (no puedes usar pthread en Windows por ejemplo).

Cita:
esto lo pregunto por que los pthreads que creo se ejecutan de manera "paralela" por lo que me surge la pregunta de que ocurre si dos o mas pthread acceden la caja de texto y quieren escribi "Aqui estoy"
Para evitar esto, pthread dispone de una herramienta: mutex (semáforo). La idea es mirar el semáforo antes de acceder a cualquier dato compartido, si está en rojo se esperará. Si está en verde pasará y lo pondrá en rojo (es tu responsabilidad desbloquear el semáforo cuando termines la operación).

Puede que ya sepas algo sobre tema, pero te pongo un ejemplo por si las moscas:

Código C++:
Ver original
  1. pthread_mutex_t mutex; // identificador mutex (variable global)
  2.  
  3. void* Hilo(void* param)
  4. {
  5.  
  6. // Inicio del hilo
  7.  
  8. pthread_mutex_init(&mutex, NULL); // creando mutex (por defecto esta desbloqueado)
  9.  
  10. variable = variable*2+3; // operaciones ajenas
  11.  
  12. //...
  13.  
  14. // quiero acceder a un recurso compartido.
  15.  
  16. pthread_mutex_lock(&mutex); // comprueba el mutex, si esta libre lo bloqueará, si no esperará a que se ponga en verde
  17.  
  18. acceder_recurso_compartido();
  19.  
  20. pthread_mutex_unlock(&mutex); // desbloqueamos el mutex
  21.  
  22. }

En lugar de variable global puedes pasar su dirrecion como paramétro (mismo metodo que con la clase).

Última edición por amchacon; 22/05/2013 a las 12:26
  #7 (permalink)  
Antiguo 26/05/2013, 20:24
 
Fecha de Ingreso: mayo-2011
Mensajes: 49
Antigüedad: 13 años, 6 meses
Puntos: 0
Respuesta: Pthread tipo c -> c++

Paso a comentar mi experiencia con el manejo de pthreads tipo c en c++....

Como escribí en un post anterior creé una función publica dentro de mi clase formulario par escribir dos cuadros de texto diferentes creyendo que no tendría problemas ..pero evidentemente no fue así ,según párese la clase principal no separa los eventos de dos clases diferentes pertenecientes a el, motivo por el cual los textos se cruzaban en el mejor de los casos ,a veces se corrompían todas las etiquetas y en la mayoría de los casos se segmentaba el programa....:(


Así que llegue a a la conclusión que lo mejor para manejar pthreads es hacerlos lo mas independientes posible o en su defecto usar semáforos que por lo que he leído hay que tener bastante cuidado al usarlos..

según leí en un documento en internet en el cual explican que el desbloqueo del mutex no grantiza que sea seguro acceder al recurso compartido.

el documento se llama Taller de pthreads
y explican lo siguiente


... Peligroso...
pthread mutex lock(&m)
pthread cond wait(&vc, &m)
pthread mutex unlock(&m)
usar paquebote(...); ///recurso compartido


....Inseguro....
pthread mutex lock(&m)
if(!hay paquebote)
pthread cond wait(&vc, &m)
pthread mutex unlock(&m)
usar paquebote(...);


....Correcto...
pthread mutex lock(&m)
while(!hay paquebote)
pthread cond wait(&vc, &m)
pthread mutex unlock(&m)
usar paquebote(...);

no comprendo muy bien como funciona la comprobación extra ....alguien si lo capta???
  #8 (permalink)  
Antiguo 27/05/2013, 01:26
 
Fecha de Ingreso: julio-2012
Mensajes: 375
Antigüedad: 12 años, 4 meses
Puntos: 28
Respuesta: Pthread tipo c -> c++

Te lo dije, C++ no tiene maquina virtual ni rutina que controle esas cosas puesto que dependen del sistema operativo. De hecho, C++ es incapaz de separar dos clases (el compilador las transforma en simples funciones)

Ese ejemplo es un pelín más "avanzado". El ejemplo de semáforos ya te lo posteé y es válido para que escribas en el cajetín sin problemas.

Lo que cita ahí es el pthread_cond_wait. Que por decirlo de alguna forma, es para realizar sentencias condicionales entre threads de una forma más rápida. Aquí un ejemplo:

Código C:
Ver original
  1. void* Hilo1(void* param)
  2. {
  3.    pthread_mutex_lock(&mutex);
  4.  
  5.    pthread_cond_wait(&condicicion, &mutex ); // esperamos que se cumpla la condicion
  6.  
  7.    printf("Condicion cumplida");
  8.  
  9.    pthread_mutex_unlock(&mutex);
  10. }
  11.  
  12. void* Hilo2(void* param)
  13. {
  14.    pthread_mutex_lock(&mutex);
  15.  
  16.    if (param) == NULL)
  17.        pthread_cond_signal(&condicicion, &mutex );  // Mensaje de cumplido
  18.  
  19.    printf("Condicion cumplida 2");
  20.  
  21.    pthread_mutex_unlock(&mutex);
  22. }

Ahora bien, el estándar dice que se debe haber comprobado la condición desde el otro thread por si "acaso". En el ejemplo propuesto:

Código C:
Ver original
  1. while(!hay paquebote)
  2. pthread cond wait(&vc, &m)

Mientras el recurso paquebote no tenga un valor válido (NULL) no se usará. En la práctica solo se usará una iteración del bucle pero te cubres las espaldas por si necesitarás más.
  #9 (permalink)  
Antiguo 14/07/2013, 10:36
 
Fecha de Ingreso: mayo-2011
Mensajes: 49
Antigüedad: 13 años, 6 meses
Puntos: 0
Respuesta: Pthread tipo c -> c++

Hola estoy de vuelta por aquí después de pelearme por un tiempo con PHP .y al retomar el tema de los pthreads en C me encontré con problemas que no había tenido en cuenta antes uno de ellos es que al testear mi aplicacion C que atiende múltiples clientes TCP de manera concurrente me di cuenta que mi aplicación no suelta los recursos de ram usados por cada pthread y al responder a 2000 peticiones me doy cuenta que mi aplicación dejo sin recursos de ram al servidor.

Esto no lo había tenido en cuenta antes y me párese un problema grave .

La "muerte" de mi pthread la escribo de la siguiente manera

pthread_t tid=pthread_self();
pthread_detach(tid);
return(0); //esto lo hago para que salte al final del pthread creo que no esta muy bien hecho.

es esto correcto ????
de que manera se aconseja hacerlo??

gracias por la atencion y astaluego.
  #10 (permalink)  
Antiguo 14/07/2013, 14:36
 
Fecha de Ingreso: julio-2012
Mensajes: 375
Antigüedad: 12 años, 4 meses
Puntos: 28
Respuesta: Pthread tipo c -> c++

Sustituye return 0; por pthread_exit:
http://pubs.opengroup.org/onlinepubs...read_exit.html

A su vez, comprueba los errores de detach:

Código C:
Ver original
  1. int Buffer = pthread_detach(tid);
  2.  
  3. if (Buffer == EINVAL) // Imprimir "Not joinable thread"
  4. if (Buffer == ESRCH) // ID no válida
http://pubs.opengroup.org/onlinepubs...ad_detach.html
  #11 (permalink)  
Antiguo 21/07/2013, 10:06
 
Fecha de Ingreso: mayo-2011
Mensajes: 49
Antigüedad: 13 años, 6 meses
Puntos: 0
Respuesta: Pthread tipo c -> c++

hola amchacon muchas gracias por su colaboracion ,me ha sido de gran ayuda ...pero desafortunadamente en el ultimo topico que publique no he podido solucionar el problema.

pthread_t tid=pthread_self();
pthread_detach(tid);
pthread_exit(null); //hize esta modificacion y reemplaza bien al return pero al crear muchos pthreads la memoria no se libera.

ademas realize el siguiente cambio en la creacion del pthread pero sigue sin funcionar

pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//en teoria lo que hace es decirle al programa que no guarde nada de lo que sucedio en el pthread..
pthread_create(&hilo, &attr, mi_hilo, arg);//y se le pasa como atributo.

mi programa crea un hilo para la espera de conexiones que a su vez crea los hilos que atienden cada conexion. ya tiene cierto grado de complejidad y no veo que mas me pueda estar causando este problema a parte de los hilos hijos que atienden cada conexion.

los hilos son muy pequeños...cada 200 conexiones me consumen 2 megas no es mucho pero me queda la espinita de que es lo que ocurre.

bueno se me olvidaba mencionar algo que encontre por ahi que crei era mi problema los procesos zombies pero hasta donde he mirado mis hilos no quedan en este estado ..

????????????????????

gracias y astaluego.

Última edición por williamfj; 21/07/2013 a las 10:35

Etiquetas: funcion, programa, tipo, variable
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 06:06.