[Programación] Re: [Programación] Re: [Programación] Re: [Programación] Re: [Programación] Cantidad de datos antes de fgets

Gustavo Guillermo Pérez programacion@lugro.org.ar
Fri, 3 Jun 2005 17:07:09 -0500


El Viernes, 3 de Junio de 2005 16:12, Nicolás Aimetti escribió:
Gracias por responder
> En el primer mail vos decías que no querías usar threads, pero por lo
> visto ahora te decidiste a usarlos, así que la asumo que vas a usar
> threads...
Si, no me quedó otra salida fácil...
> Por lo que he interpretado vos lanzas una función (o thread) scan_joy()
> para cada dispositivo usb que tenés conectado, y ese thread se encarga
> de leer los datos de dicho dispositivo, por tanto no debería preocuparte
> que un thread en especial esté bloqueado en la espera de datos del
> dispositivo, pues esto en nada afecta a los otros, pues que uno este
> bloqueado en una llamada read() no bloquea a los demás threads.
Yep, es cierto, sólo que al quedar bloqueados devfs, queda bloqueado si 
desconecto el joypad, tengo que poder conectar otro sin reiniciar el 
programa, resulta que al quedar bloqueado el thread con un nodo que 
desapareció, llego a tener 2 joypads y se llaman /devfs/input/js9 o js10 que 
como son numeros más grandes jamás vuelvo a poder usar el js0 ese thread 
quedó bloqueado eternamente hasta terminar, no quiero lanzar más de 8 threads
> Otra cosa...
> Por ejemplo,
>     fgets(buff,IN_BYTES-offset,rfile);
>     //permitir a los otros threads hacer algo
>     sched_yield();
>     sleep(0.5+i/10);
> Esté fragmento de código no lo entiendo  muy bien que digamos. O sea,
> primero llamás a fgets, lo cual podría bloquear al thread en cuestión
> hasta que haya datos disponibles. Una vez que esto se cumple, o sea, que
> hay datos disponible, o que hubo algún error (lo cual _debería_ ser
> chequeado), sigue el curso del thread.
> [Tené en cuente además que feof no chequea el caso de que haya errores
> en el archivo, como por ejemplo que el archivo se cerro. Por tanto
> deberías hacer algo como:
Es cierto, error mío, pero el sched_yield lo puse porque cuando llegaban las 
señales al mismo tiempo de varios controles, no se leían correctamente los 
demás o se enlentecía la lectura. la pausa debería ser solo 1, la puse para 
no leer tan rápido, se me escapó la declaración de sleep...
Pero tengo una duda terrible, al compilarlo no saltó ni un solo warning y 
realmente las pausas 0.5 eran de medio segundo :( por eso ni revisé la 
declaración.
>  if ( fgets(buff,IN_BYTES-offset,rfile) == NULL ) { <tratamiento del
> error> }
también error mío no revisar eso, pero cuando desconecto el joypad fgets no 
reacciona dando error ahí se queda.
> al final del mail  pongo un ejemplo de lo que digo acerca de feof, como
> para que te veas lo que te digo, creo que esto tiene mucho que ver en
> por que no anda bien la cosa. ]
> Luego comentas "permitir a los otros threads hacer algo" y llamás a
> sched_yield(): por más que no llamases a sched_yield() los demás threads
> deberían poder estar haciendo algo. O sea, no es necesario que llames a
> sched_yield(), es redundante,  por lo menos por lo que yo interpreto de
> lo que acá estoy viendo.
> Luego usas  un sleep que según las prioridades de los operadores que
> usas se puede reescribir como:
>    sleep( 0.5 + (i/10) );
> Por tanto a un entero (i/10) le sumás un double 0.5 lo cual da un double
> (el cual nuevamente es casteado a int), pero la función sleep:
>     unsigned int sleep(unsigned int seconds);
> toma como parámetro un unsigned int, de lo cual deduzco que en este
> código hay algún tipo de confusión.
> Además, suponiendo que necesitases esperar un tiempo como para que
> alguna condición X se cumpliese, entonces te combiene usar la familia de
> funciones pthread_cond_* para conseguir esto.
>
> Se podría emular de alguna manera la función available()  de java, o
> hacer una función para chequear si hay datos disponibles  en el archivo
> antes de leer y demás, pero personalmente pienso que si estás trabajando
> con threads nada de esto es necesario. O sea, cada thread trabaja por su
> cuenta, así que no hay ningún problema con que un thread en particular
> quede bloqueado a la espera de datos, los demás siguen trabajando.
>
> La otra opción que tenés sino es usar en vez de threads la función
> select() o poll(). Pero creo que con threads debería andar todo bien.
>
> Acerca de lo que pasa cuando desconectas el joypad habría que ver bien
> que pasa en el main() y demás como para poder decir algo.
>
> Ejemplo de por que NO sirve nomás usar feof para controlar si se puede
> leer de un archivo:
>
> #include <stdio.h>
> #include <unistd.h>
>
> baja main(void){
>     int i=0;
>     while(!feof(stdin)){
>         char buff[1];
>         if (! i++ ){
>             if( fclose(stdin)==EOF ){ printf("error!!!"); }
>             printf("Se cerro el archivo!!!\n");
>             sleep(1);
>         }
>         printf("y sigue girando... girando...\n");
>         if ( fgets(buff,1,stdin) == NULL ) printf("Mienrtras que fgets
> SI da error\n");
>     }
>     return 0;
> }
>
> Espero que te sirva de algo.

exacto, gracias por el ejemplo es muy ilustrativo, creo que voy a tener que 
revisar el código del driver del usbhid y el del joystick para que cierren el 
archivo, o lo más probable, que el culpable sea devfs, voy a ver en los 
sources del kernel porque por eso no se destraban, porque no se cierra, 
"queda abierto".
> Saludos,
>              Nicolás.

Mil gracias.
-- 
Gustavo Guillermo Pérez
Compunauta uLinux
www.ulinux.tk