¡Hola! El Tue, Feb 01, 2011 at 09:15:22AM -0300, Ricardo Albarracin B. escribio: > El Mon, 31 Jan 2011 23:28:42 -0300 > Aldrin Martoq <amar...@dcc.uchile.cl> escribió: > > > Mejor cuéntanos qué pretendes hacer... > > > > Precisamente eso.... reasignar más tiempo de CPU a algunos procesos > críticos para evitar la perdida de datos en capturas de hasta 50KBPS a > través de una USB, hay un buffer que se llena y hay datos que se > pierden. La recoleción de datos llega a varios millones imagina esa > taza en 5 a 10 minutos. > [...] > > El caso mío es distinto al que planteas, ya que uso un sistema de > captura de datos de alto rendimiento y una opción es ir a un sistema > operativo de tiempo real, pero antes es agotar todos los recursos antes > de llegar a ese extremo, el problema lo resuelvo con máquinas más > potentes pero no es la idea, el tema es con máquinas por ejemplo como > las Atom.
Lo que más te conviene aquí es cambiar la clase de schedulling del programa, pasar de la clase estándar a la clase round-robin. Esto garantiza que tu aplicación va a recibir CPU cada cierto tiempo por lo menos. Para hacerlo, basta con utilizar la llamada sched_setscheduler(), ve en su página de manual. En nuestro caso, agregamos esto: void set_priority() { struct sched_param sp; sp.sched_priority = 10; sched_setscheduler(0, SCHED_RR, &sp); } Todas las tareas en round-robin tienen más prioridad que las tareas estándares, esto significa que si usas el 100% de CPU, nada más se ejecutará en tu computador. Esto no es un problema si la aplicación sólo recibe datos, ya que debería realizar la recepción y luego volver a esperar más datos. El problema ahora es que no quieres que la aplicación tenga permisos de super-usuario. Si usas Linux mayor a 2.6.12, la solución es cambiar el límite de prioridad permitida de los procesos por medio de la capacidad "RLIMIT_RTPRIO" usando setrlimit. Esto se hace con el siguiente pseudocódigo: // Programa ejecutado con UID=0, cambia los límites setrlimit(...); if(!fork()) { // Cambia a usuario 1000 (por ejemplo) setuid(1000); // Ejecuta el programa execve(....); } // Termina. exit(0); Obviamente, con manejo de errores, etc. Lamentablemente el programa "padre" debe todavía ser root, esto es difícil de evitar, ya que de alguna manera se tiene que dar el permiso. Nota que en versiones de Linux mayores a 2.6.25 puedes también fijar el límite "RLIMIT_RTTIME", el cual limita el total de tiempo que un proceso de prioridad RT puede utilizar de una sola vez. Esto sirve para impedir que un proceso RT use el 100% de CPU y haga que el resto del sistema no responda. Ve en el manual de "setrlimit". Por último, si insistes en que el proceso inicial (que fija los límites) no sea ejecutado como root, puedes utilizar el sistema de capacidades de Linux, ve capabilities(7), con énfasis en la sección llamada "File Capabilities". La gracia es que, si usas un sistema de archivos que lo soporte, puedes asignar a un ejecutable la capacidad "CAP_SYS_NICE", usando "setcap cap_sys_nice+p programa". Lee bien, eso si, lo que esto permite al proceso. Lamentablemente, en UBIFS que usamos aquí no hay soporte para capabilities. Daniel.