[PC]Multithreading... me mata...

hola, como sabreis estoy haciendo un juego. Bueno y por necesidad tengo que usar hilos porque cuando quiero captuar una imágen de la webcam el pc "creo" que se queda esperandola. Bueno ya tengo hecho el hilo para capturar de la webcam y tal sin problema pero aún se me queda congelado...

podría ser esto problema de la política y/o prioridad del hilo? y si es así ... alguien sabe como cambiarla? he mirado muchisimo por internet y nada :(. ha por cierto estoy usando pthread-win32 que vienen a ser como ls pthread de toda la vida... ufff por cierto no veais como me jode esto de que la webcam se me bloquee.
estás seguro de que eres capaz de recuperar la imagen de la webcam ? es decir, el hilo no se quedará bloqueado porque está esperando a que pase algo, verdad ?

si estás seguro de que lo hace bien lo que tienes que hacer es un join en el hilo principal para que siga cuando el otro ya ha terminado

si son igual que los posix de linux:

http://www.llnl.gov/computing/tutorials/pthreads/

y concretamente: http://www.llnl.gov/computing/tutorials/pthreads/#Joining


nunca he usado eso de pthread-win32 así que no sé si será igual, pero si sigue el estandar debería serlo


edito: después de volver a leer tu pregunta creo que lo que tienes es un problema obteniendo la imagen (bueno, tú mismo lo dices jeje) y no con los hilos. de todas formas no borro lo que te he puesto arriba porque lo mismo te vale de ayuda :D

de lo de usar la webcam no tengo ni la más remota idea. lo siento
saulotmalo escribió:hola, como sabreis estoy haciendo un juego. Bueno y por necesidad tengo que usar hilos porque cuando quiero captuar una imágen de la webcam el pc "creo" que se queda esperandola. Bueno ya tengo hecho el hilo para capturar de la webcam y tal sin problema pero aún se me queda congelado...

podría ser esto problema de la política y/o prioridad del hilo? y si es así ... alguien sabe como cambiarla? he mirado muchisimo por internet y nada :(. ha por cierto estoy usando pthread-win32 que vienen a ser como ls pthread de toda la vida... ufff por cierto no veais como me jode esto de que la webcam se me bloquee.


Humm, no entiendo bien el problema ¿que se te bloquea exactamente? ¿el hilo que controla la captura de la camara? ¿o el resto del juego?

Si es el de captura, probablemente sea lo normal, por que si no, no necesitarias crear varios hilos

Pero si te bloquea el resto del juego o va muy despacio, puede deberse a que establezcas en el hilo de la camara una prioridad alta y el hilo sea a tiempo real.

Pero existe una segunda razon que podria hacer que ese hilo se bloqueara: que tu te quedes esperando la respuesta de la camara o que intentes acceder a esa respuesta, llamando a una funcion que en la captura se bloquea, para recbir la respuesta de la camara.

En este caso, deberias hacer que la captura pasara todos los datos en un buffer y activar un flag (en una variable) que indicara cuando el hilo del juego puede leer esos datos (y borrarlo una vez leido)


Tambien podria ocurrirte otra cosa: que el hilo de captura se este llamando continuamente... y claro, solo deberias llamarlo cada cierto tiempo (lo mejor seria que el juego le indicara en un flag, cuando debe empezar a capturar y el resto del tiempo, el hilo estuviera llamando a alguna funcion que devolviera el control)

En fin, seguramente sea alguna de estas cosas.
Quizas hagas un sleep en algun lado y no vuelvas a despertar el hilo. Entonces se queda en la cola de bloqueados permanentemente.
a ver... os explico con detenimiento... ( que la cosa es jodida ).

Prueba 1. tengo un bucle principal en mi juego (bucle infinito) le digo cada 60 frames ( 1 segundo) crea un hilo y coge una imagen de la cámara. Entonces el juego se para por un poco y sigue (sin usar esa imagen para nada solamente adquirirla.

Prueba2. tengo un bucle principal para el juego, creo un hilo con un bucle infinito que va leyendo de la cámara entonces el juego le cuesta muchisimo de arrancar, por eso "creo" que el problema está en la prioridad asignada.

sabeis algun tipo de hilos en win32 y que pueda asignar la prioridad?
saulotmalo escribió:a ver... os explico con detenimiento... ( que la cosa es jodida ).

Prueba 1. tengo un bucle principal en mi juego (bucle infinito) le digo cada 60 frames ( 1 segundo) crea un hilo y coge una imagen de la cámara. Entonces el juego se para por un poco y sigue (sin usar esa imagen para nada solamente adquirirla.

Prueba2. tengo un bucle principal para el juego, creo un hilo con un bucle infinito que va leyendo de la cámara entonces el juego le cuesta muchisimo de arrancar, por eso "creo" que el problema está en la prioridad asignada.

sabeis algun tipo de hilos en win32 y que pueda asignar la prioridad?


Hombre, la prioridad la puedes fijar con la funcion SetThreadPriority()
pero el problema es que debes suspender el hilo de vez en cuando, cuando no tenga que hacer algo.

La funcion de fijar prioridad, necesita que le pases como primer parametro, el handler del hilo creado y como segundo, la prioridad, claro (lo normal THREAD_PRIORITY_NORMAL)

Para suspender un hilo de forma temporal, usa la funcion Sleep(tiempo); donde tiempo son los milisegundos que estará suspendido, antes de volver a tratar de activarse (si no recuerdo mal, el timer que se usaba de base, cambia 18,2 veces por segundo, asi que no sera muy exacto, me temo).

Eso si, procura que el Sleep se llame solo cuando hayas acabado la captura y hasta que reciba otra orden de capturar (desde el hilo del juego) y prueba varios valores de espera, hasta que encuentres uno que te resulte optimo.
se que es mucha faena... pero podrías hacerme un pequeño manual o algo para crear un hilo de la manera que tu dices? esque no se que metodo has gastado, hilos windows? no he encontrado ni la API en internet :( ahora mismo estoy usando pthreads w32 que es parecido a pthreads y esa funcion no recuerdo haberla visto, que valores serían para subir y bajar la prioridad?

gracias como siempre!
saulotmalo escribió:se que es mucha faena... pero podrías hacerme un pequeño manual o algo para crear un hilo de la manera que tu dices? esque no se que metodo has gastado, hilos windows? no he encontrado ni la API en internet :( ahora mismo estoy usando pthreads w32 que es parecido a pthreads y esa funcion no recuerdo haberla visto, que valores serían para subir y bajar la prioridad?

gracias como siempre!


Busca un include de nombre winbase.h (al menos en Minsys está)
Sobre la API de Windows, ¿porque no te pasas por MSDN?

Mira, solo googleando un poco:

http://msdn2.microsoft.com/en-us/library/ms686277.aspx

Aqui estarian todas las funciones:

http://msdn2.microsoft.com/en-us/library/ms684847.aspx
Te juro que estube toda la noche ayer buscando por google ( incluso en msdn) y nada ufff muchas gracias por la info! ahora a ver si consigo hacer un hilo con esto... es la primera vez que lo veo en la vida... luego comento que tal.

EDIT:

Ale probado... hilos... y nada cuando pilla la imagen se congela... igual es porque tengo un amd?? o porque la webcam es un eyetoy? joer nada no hay manera... ahora pondré otro hilo a ver quien me hecha una mano a encontrar otra librería ya que tito google se está portando mal conmigo ultimamente.
Pues nose,podria ser un tipico problema de sincronizacion. Parece que, o bien tu hilo siempre se cuela delante de los demas procesos o los demas procesos se cuelan delante de tu hilo y tu programa no sigue el orden correcto de ejecucion entre los hilos.

La solucion a estos problemas suele ser el uso de tecnicas como semaforos, monitores, regiones criticas, variables condicion.... hay muchas formas de tener bien ordenados los procesos en cualkier situacion sin producir inanicion ni espera activa.

Pues eso, yo creo q deberias mirar modos de sincronizacion entre procesos.


un saludo.... y ojala des con la solucion [oki]
no creo que sea tema de sincronización ya que he puesto un sleep 100 para el proceso y nada ... no funciona, y eso que no comparten SC ni nada:S yo estoy flipando...
saulotmalo escribió:Prueba2. tengo un bucle principal para el juego, creo un hilo con un bucle infinito que va leyendo de la cámara entonces el juego le cuesta muchisimo de arrancar, por eso "creo" que el problema está en la prioridad asignada.
prioridad?


En esta prueba tienes un hilo que es el que lee de la webcam y el principal, en el principal estas usando lo que lees con la webcam?
Aunque tengas puesto un sleep puede ser problema de sincronizacion. Prueba a poner un mutex.

PD:que estas usando al final para capturar desde la webcam?, yo tenia pensado hacer algo parecido y pense hacerlo con directx, lo que pasa es que estoy con los examenes liadisimo.

Suerte!!!
Sobre lo que dices.. solo capturo la imagen, no hago nada más con ella... alguien con webcam podría probar las pruebas para ver si es problema de la cámara? o drivers?

estoy con open cv, pero ya te digo que tengo el problema mencionado y me parece una grandisima putada... en fin.
saulotmalo escribió:Sobre lo que dices.. solo capturo la imagen, no hago nada más con ella... alguien con webcam podría probar las pruebas para ver si es problema de la cámara? o drivers?

estoy con open cv, pero ya te digo que tengo el problema mencionado y me parece una grandisima putada... en fin.


¿no sera que no inicializas bien la camara (o que de algun error) y causas algun tipo de bloqueo?

Por lo que se ve, el bloqueo se produce durante la captura yy tiene toda la pinta de ser un fallo de ese tipo
a ver esque el problema es que tengo que gastar la librería opencv y apenas son líneas para inicializar la webcam... he mirado la api y tiene pocas cosas... pero weno. Bloqueo... total no... pero parcial si... mirad tengo un amd 3000+ am2 1 gb de ddr 2 y una 7600 gt y me saca 40 frames inconstantes un cubo y la cámara capturando sin hacer nada con la imagen... no tengo ni idea de que puede estar pasando.
Pues no se chico, no conozco esa libreria y no se donde puede estar el problema.

Solo se me ocure que o bien ees un fallo o error durante la inicializacion o que tal vez, una funcion te devuelve un buffer que debas liberar y si no lo haces, te vaya llenando la memoria de "basura" (y acabes tirando de memoria virtual)

La verdad es que es raro... seria mejor que te asegures de que esas funciones trabajan bien con un ejemplo y luego trates de hacerlo multihilo
no se la verdad... de momento he decido ir a tutorias de profesores que aunque no me estén dando clases y tal siempre les puedes preguntar ya que les gustan este tipo de trabajos... a ver si consigo sacar un juego wapo le pondré el logo de eol ;)

UPDATE:

You'll likely want to place the cvQueryFrame() call in a thread. It
blocks until a new frame is ready, time that is usually needed for your
program's logic and/or graphics updates.

esto quizas es lo que estabamos buscando, se bloquea, era lo que pensaba pero lo que no entiendo porque el hilo principal tambien se bloquea... en fin sigo trabajando :)
Prueba a hacer lo siguiente:

En el hilo del juego, ejecuta primero la funcion GetCurrentProcess()
que te devolvera un handle (que deberas asignar a una variable de tipo HANDLE)

Luego llama la funcion SetPriorityClass, de esta forma:

SetPriorityClass(HANDLE, REALTIME_PRIORITY_CLASS);

Con esto haras que tu aplicacion pase a ejecutarse en modo real y no en idle y es posible que eso te solucione el problema (puede ser que la camara se este ejecutando en modo real y al trabajar tu aplicacion en modo IDLE, baje el rendimiento)


Puede probar con diferentes clases de procesos, te dejo el enlace de la funcion, para que sepas las diferentes clases.

http://msdn2.microsoft.com/en-us/library/ms686219.aspx
He dado un paso de gigante y creo que puedo ayudar a gente con mi mismo problema :) bueno ya consigo framerate constante y capturar de cámara.

el truco era... crear un proceso... no entiendo que con un proceso pesado funcione y con un proceso liger no... alguien sabe comunicar procesos entre si? bueno ahora mismo estoy mirando la info de msdn al respecto... a ratos incomprensible! pero bueno... más o menos...

Por cierto pensais que se podrán comunicar bien dos procesos usando una tubería? solo le tengo que pasar 1 dato y con que se actualize 10 veces por segundo perfecto supongo que en vez de coger 30 fps o 50 cogeré 20 o algun numero bonito y luego le diré a mi programa que las coja de la tubería con un thread ( por si se bloquea )
18 respuestas