2012-08-16 10 views
6

He escrito muchos programas C para microcontroladores, pero nunca uno que se ejecuta en un sistema operativo como Linux. ¿Cómo decide Linux cuánto tiempo de procesamiento darle a mi aplicación? ¿Hay algo que deba hacer cuando tenga tiempo de inactividad para decirle al sistema operativo que haga otra cosa y vuelva a consultarme más tarde para que otros procesos también puedan tener tiempo de ejecución? ¿O el sistema operativo simplemente hace eso automáticamente?¿Qué debería hacer el programa C en tiempo de inactividad cuando se ejecuta en Linux?

Editar: Agregar más detalles Mi programa c tiene un planificador de tareas. Algunas tareas se ejecutan cada 100 ms, algunas se ejecutan cada 50 ms y así sucesivamente. En mi bucle de programa principal, llamo a ProcessTasks, que verifica si alguna tarea está lista para ejecutarse, si ninguna está lista llama a una función inactiva. La función inactiva no hace nada pero está ahí para poder alternar un pin GPIO y controlar el tiempo de inactividad con un O'scope ... o algo así si lo deseo. Entonces, ¿debería llamar a sched_yield() en esta función inactiva?

Respuesta

6

Linux ¿Cómo decidir cuánto tiempo de procesamiento para dar mi solicitud

Cada planificador constituye su propia mente. Algunos te recompensan por no usar tu parte, algunos dados de rollo que intentan predecir lo que harás, etc. En mi opinión, solo puedes considerarlo mágico. Después de ingresar al ciclo, el programador mágicamente decide que nuestro tiempo está activo, etc..

¿Hay algo que tengo que hacer cuando tengo tiempo de inactividad para decirle al sistema operativo para ir a hacer otra cosa

Es posible llamar a sched_yield. Nunca lo llamé, ni sé de ninguna razón por la que uno quisiera. El manual sí dice que podría mejorar el rendimiento.

O es que el sistema operativo acaba de hacer eso de forma automática

Es sin duda lo hace. Es por eso que lo llaman "preemptive" multitarea.

+0

Así que las otras respuestas dicen de usar de sueño () ¿Debería llamar a sleep() y sched_yield()? si es así, ¿en cuál debería llamarse primero? – PICyourBrain

+0

@PICyourBrain Lea el manual. El rendimiento dejará en ejecución su proceso si no hay nada más que hacer, mientras que "dormir" hará que su proceso espere inequívocamente. – cnicutar

+0

si está implementando un spinlock, desea llamar a sleep (0) o sched_yield() cada vez que no se realiza el bloqueo. – Arvid

5

Depende de por qué y cómo tiene "tiempo de inactividad". Cualquier llamada a una función de E/S de bloqueo, esperando en un mutex o durmiendo, automáticamente desprogramará su hilo y permitirá que el sistema operativo avance con otra cosa. Solo algo como un bucle ocupado podría ser un problema, pero eso no debería aparecer en ningún caso.

Su programa solo debería tener un "bucle infinito" central. Si hay alguna posibilidad de que el cuerpo del bucle "se quede sin trabajo", entonces sería mejor si pudiera hacer que el bucle realice una de las funciones del sistema anteriores, lo que haría que toda la amabilidad aparezca automáticamente. Por ejemplo, si su bucle central es un epoll_wait y todas sus E/S, temporizadores y señales son manejados por epoll, llame a la función con un tiempo de espera de -1 para que duerma si no hay nada que hacer. (Por el contrario, llamarlo con un tiempo de espera de 0 lo haría ocupado-loop – ¡malo!).

+0

he agregado más información a mi pregunta – PICyourBrain

+1

@PICyourBrain: Parece que podrías hacer todo eso con epoll. Los temporizadores se pueden configurar a través de 'timerfd', y supongo que otros eventos también podrían manejarse a través de los descriptores de archivos. Dormir en un 'epoll_wait' es una forma eficiente de pasar el tiempo de inactividad. –

1

Las otras respuestas de la OMI están entrando en demasiados detalles. La cosa simple de hacer es:

while (1){ 
    if (iHaveWorkToDo()){ 
     doWork(); 
    } else { 
     sleep(amountOfTimeToWaitBeforeNextCheck); 
    } 
} 

Nota: esta es la solución simple que es útil en una aplicación de subproceso único o como el caso en que usted no tiene nada que ver por un período de tiempo determinado; solo para obtener algo decente trabajando.La otra cosa sobre esto es que sleep invocará cualquier función de rendimiento que prefiera el os, por lo que en ese sentido es mejor que una llamada de rendimiento específica.

Si desea obtener un alto rendimiento, debe esperar eventos.

Si usted tiene sus propios eventos Será algo como sigue:

Lock *l; 
ConditionVariable *cv; 

while (1){ 
    l->acquire(); 
    if (iHaveWorkToDo()){ 
     doWork(); 
    } else { 
     cv->wait(lock); 
    } 
    l->release(); 
} 

En una situación de tipo de red que será más como:

while (1){ 
    int result = select(fd_max+1, &currentSocketSet, NULL, NULL, NULL); 
    process_result(); 
} 

+0

waitForSomeEvent en lugar de solo dormir – CyberDem0n

+0

@ CyberDem0n Sí, estaba probando la segunda parte como usted comentó. Solo estoy tratando de dar algunas soluciones diferentes para las personas que no quieren adentrarse demasiado en el mundo de los subprocesos múltiples. también parece partir de la pregunta de que está buscando dormir. – chacham15

+0

@ chacham15 Supongo que quieres decir l-> adquirir y l-> liberar, ¿no?> – PICyourBrain

Cuestiones relacionadas