LKMPG: Pianificare compiti: differenze tra le versioni

Vai alla navigazione Vai alla ricerca
nessun oggetto della modifica
Nessun oggetto della modifica
Nessun oggetto della modifica
Riga 2: Riga 2:




== Pianificare i compiti ==
== Pianificare i tasks ==




Molto spesso, abbiamo dei compiti proprietari che devo essere eseguiti in tempi precisi, o molto spesso. Se il compito è eseguito da un processo, possiamo metterlo nel file ''crontab''. Se il processo invece è eseguito da un modulo del kernel, abbiamo due possibilità. La prima è di mettere un processo nel file '' crontab'', che attiverà il modulo tramite una system call quando necessario, per esempio aprendo un file. In ogni caso questo metodo è molto inefficente -- si esegue un nuovo precesso di crontab, si legge un nuovo eseguibile nella memoria, e tutto solo per attivare il modulo del kernel che è comunque caricato nella memoria.
Molto spesso, abbiamo dei tasks proprietari che devo essere eseguiti in tempi precisi, o molto spesso. Se il task è eseguito da un processo, possiamo metterlo nel file ''crontab''. Se il processo invece è eseguito da un modulo del kernel, abbiamo due possibilità. La prima è di mettere un processo nel file '' crontab'', che attiverà il modulo tramite una system call quando necessario, per esempio aprendo un file. In ogni caso questo metodo è molto inefficente -- si esegue un nuovo precesso di crontab, si legge un nuovo eseguibile nella memoria, e tutto solo per attivare il modulo del kernel che è comunque caricato nella memoria.


Invece di fare in questo modo, si può creare una funzione che sarà chiamato una volta per ogni interrupt. La strada da seguire è creare un compito, tenuto in una struttura workqueue_struct, che terrà un puntatore sulla funzione. Successivamente, si userà queue_delayed_work per mettere il compito in una lista chiamata my_workqueue, che è la lista dei compiti che saranno eseguiti nel prossimo interrupt. Poichè vogliamo che la funzione sia portata in esecuzione, abbiamo bisogno di metterela ancora nella lista my_workqueue ogni volta che è chiamata, per il prossimo interrupt.
Invece di fare in questo modo, si può creare una funzione che sarà chiamato una volta per ogni interrupt. La strada da seguire è creare un task, tenuto in una struttura workqueue_struct, che terrà un puntatore sulla funzione. Successivamente, si userà queue_delayed_work per mettere il task in una lista chiamata my_workqueue, che è la lista dei tasks che saranno eseguiti nel prossimo interrupt. Poichè vogliamo che la funzione sia portata in esecuzione, abbiamo bisogno di metterela ancora nella lista my_workqueue ogni volta che è chiamata, per il prossimo interrupt.


C'è ancora un punto che dobbiamo ricordare. Quando un modulo è rimosso tramite '''rmmod''', prima di tutto è controllato il conteggio delle sue referenze. Se è zero, è eseguito ''module_cleanup''.Poi, il modulo è rimosso dalla memoria con tutte le sue funzioni. E' importante arrestare correttamente un modulo,o potrebbero accadere imprevisti spiacevoli. Si guardi il codice sotto dove si nota come può essere fatto in un modo sicuro.
C'è ancora un punto che dobbiamo ricordare. Quando un modulo è rimosso tramite '''rmmod''', prima di tutto è controllato il conteggio delle sue referenze. Se è zero, è eseguito ''module_cleanup''.Poi, il modulo è rimosso dalla memoria con tutte le sue funzioni. E' importante arrestare correttamente un modulo,o potrebbero accadere imprevisti spiacevoli. Si guardi il codice sotto dove si nota come può essere fatto in un modo sicuro.
8

contributi

Menu di navigazione