devo gestire un pool di thread aventi differenti priorità, così ho scritto la seguente procedura di avvio filo:pthreads con tempo reale priorità
static
int startup(thrd_t *thrd, thrd_sync_t *sync, int prio)
{
pthread_attr_t attr;
int err;
struct sched_param param = {
.sched_priority = prio
};
assert(pthread_attr_init(&attr) == 0);
assert(pthread_attr_setschedpolicy(&attr, SCHED_FIFO) == 0);
assert(pthread_attr_setschedparam(&attr, ¶m) == 0);
err = pthread_create(&thrd->handler, &attr, thread_routine, (void *)thrd);
pthread_attr_destroy(&attr);
return err;
}
In linea di principio l'utente non privilegiato non dovrebbe essere consentito di eseguire questo codice: la chiamata pthread_create() dovrebbe restituire EPERM a causa delle implicazioni di sicurezza nell'esecuzione di un thread con priorità alta.
Inaspettatamente funziona per l'utente normale, ma non rispetta affatto la priorità data.
Ho provato a modificare il codice rimuovendo il pthread_attr_t
e impostando l'attributo schedulazione Una volta creato il filo:
static
int startup(thrd_t *thrd, thrd_sync_t *sync, int prio)
{
pthread_attr_t attr;
int err;
struct sched_param param = {
.sched_priority = prio
};
err = pthread_create(&thrd->handler, NULL /*&attr*/, thread_routine,
(void *)thrd);
if (err != 0) return err;
err = pthread_setschedparam(thrd->handler, SCHED_FIFO, ¶m);
if (err != 0) return err;
return err;
}
Questo approccio proposito è molto più difficile da gestire, in quanto in caso di errore Ho bisogno di uccidere il thread appena creato. Almeno sembra funzionare correttamente rispetto ai requisiti di autorizzazione (solo root può eseguirlo), ma le priorità non vengono rispettate.
Sto facendo qualcosa di sbagliato?
EDIT
Ho appena aggiunto il seguente pezzo di codice che viene eseguito da ogni filo:
static
void getinfo()
{
struct sched_param param;
int policy;
sched_getparam(0, ¶m);
DEBUG_FMT("Priority of this process: %d", param.sched_priority);
pthread_getschedparam(pthread_self(), &policy, ¶m);
DEBUG_FMT("Priority of the thread: %d, current policy is: %d and should be %d",
param.sched_priority, policy, SCHED_FIFO);
}
Con il primo metodo (cioè pthread_attr_t
approccio) risulta che il pthread_attr_setschedpolicy non è totalmente efficace, poiché la priorità è 0 e la politica non è SCHED_FIFO.
Con il secondo metodo (ovvero l'approccio pthread_setschedparam
) la funzione stampa i dati previsti, ma l'esecuzione continua a comportarsi in modo errato.
Come si determinano le chiamate non vengono rispettate? Ho riscontrato qualcosa di simile, ma l'API non è stata semplicemente implementata e non è riuscita in quanto tale. – Ioan
@Ioan: vedere la versione aggiornata della domanda. – Dacav
OT: non inserire il codice all'interno di 'assert()'. Se questo è compilato con assert disabilitato, il codice non verrà eseguito. – bstpierre