2009-09-25 12 views
25

Le librerie Boost non sembrano avere un dispositivo per l'impostazione della priorità di un thread. Questo sarebbe il miglior codice da usare su Linux o c'è un metodo migliore?Impostazione priorità del thread in Linux con Boost

boost::thread myThread(MyFunction()); 

struct sched_param param; 
param.sched_priority = 90; 
pthread_attr_setschedparam(myThread.native_handle(), SCHED_RR, &param); 

Non ho un sacco di esperienza di programmazione Linux.

+0

Arafangion: Avete qualcosa per eseguire il backup? La pagina man di linux per pthread_attr_setschedparam dice che funziona. Inoltre, la mia esperienza personale è che funziona esattamente come documentato. –

risposta

22

Questo è il modello di base per come lo farei, ma dopo aver cercato in giro non ho trovato esempi di codice, quindi suppongo che il verdetto indichi se è meglio o no.

Il problema è che boost :: thread non ha un costruttore che consente di passare attributi pthead alla creazione del thread, quindi è necessario apportare modifiche dopo l'avvio del thread. L'unico altro modo in cui so di aggirare è attraverso l'ereditarietà della schedulazione processo/thread. Salvo diversa indicazione, i nuovi thread erediteranno la pianificazione/priorità del loro creatore in modo da poter modificare il thread corrente prima di creare i thread di lavoro e quindi tornare indietro se lo si desidera. Sembra imbarazzante ma è un'alternativa.

Ecco un esempio di un esempio che si spera mostri entrambi. Potrebbe essere necessario modificare la politica e la priorità in modo appropriato ed eseguirli come root.

Prestare attenzione al modo in cui si imposta la priorità. Si applicano varie restrizioni.

#include <iostream> 
#include <boost/thread/thread.hpp> 
#include <unistd.h> 
#include <sched.h> 
#include <cstdio> 


void* threadfunc() 
{ 
    sleep(5); 
} 

void displayAndChange(boost::thread& daThread) 
{ 
    int retcode; 
    int policy; 

    pthread_t threadID = (pthread_t) daThread.native_handle(); 

    struct sched_param param; 

    if ((retcode = pthread_getschedparam(threadID, &policy, &param)) != 0) 
    { 
     errno = retcode; 
     perror("pthread_getschedparam"); 
     exit(EXIT_FAILURE); 
    } 

    std::cout << "INHERITED: "; 
    std::cout << "policy=" << ((policy == SCHED_FIFO) ? "SCHED_FIFO" : 
           (policy == SCHED_RR) ? "SCHED_RR" : 
           (policy == SCHED_OTHER) ? "SCHED_OTHER" : 
                 "???") 
       << ", priority=" << param.sched_priority << std::endl; 


    policy = SCHED_FIFO; 
    param.sched_priority = 4; 

    if ((retcode = pthread_setschedparam(threadID, policy, &param)) != 0) 
    { 
     errno = retcode; 
     perror("pthread_setschedparam"); 
     exit(EXIT_FAILURE); 
    } 

    std::cout << " CHANGED: "; 
    std::cout << "policy=" << ((policy == SCHED_FIFO) ? "SCHED_FIFO" : 
           (policy == SCHED_RR) ? "SCHED_RR" : 
           (policy == SCHED_OTHER) ? "SCHED_OTHER" : 
                  "???") 
       << ", priority=" << param.sched_priority << std::endl; 
} 


int main(int argc, char* argv[]) 
{ 
    int policy, res; 

    struct sched_param param; 

    if ((policy = sched_getscheduler(getpid())) == -1) 
    { 
     perror("sched_getscheduler"); 
     exit(EXIT_FAILURE); 
    } 

    if ((res = sched_getparam(getpid(), &param)) == -1) 
    { 
     perror("sched_getparam"); 
     exit(EXIT_FAILURE); 
    } 

    std::cout << " ORIGINAL: "; 
    std::cout << "policy=" << ((policy == SCHED_FIFO) ? "SCHED_FIFO" : 
           (policy == SCHED_RR) ? "SCHED_RR" : 
           (policy == SCHED_OTHER) ? "SCHED_OTHER" : 
                  "???") 
       << ", priority=" << param.sched_priority << std::endl; 


    policy = SCHED_RR; 
    param.sched_priority = 2; 

    if ((res = sched_setscheduler(getpid(), policy, &param)) == -1) 
    { 
     perror("sched_setscheduler"); 
     exit(EXIT_FAILURE); 
    } 

    boost::thread t1(&threadfunc); 

    displayAndChange(t1); 

    t1.join(); 

    return 0; 
} 
+2

Stavo solo cercando un rapido esempio per non passare attraverso le pagine di manuale e ho trovato questo utile. Grazie. –

+0

Rispetto a 'boost :: thread'' QThread' è davvero brillante nel reparto di essere in grado di impostare facilmente la priorità del thread. – rbaleksandar

+0

Funziona perfettamente anche con 'std :: thread'. – ollo

1

Non credo che Linux ha davvero le priorità di thread - nella maggior parte dei kernel è possibile utilizzare i livelli di 'Nice', ma questo è probabilmente su di esso (che semplificherebbe lo scheduler) - tuttavia, non tutti i sistemi Linux rispettalo! (Dipende dallo scheduler).

+0

questa risposta non corrisponde a ciò che ho visto o sentito di Linux. Forse ti stai riferendo a una versione precedente? – Alex

+0

@Alex: cosa hai sentito? È molto probabile che mi riferisca a una versione precedente oa una concezione errata di una versione precedente. – Arafangion

+0

la risposta accettata dimostra l'impostazione delle priorità dei thread e la pianificazione in linux, quindi linux ha implementato le priorità dei thread. Per quanto riguarda i livelli Nice ho trovato la documentazione: http: //git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/tree/Documentation/scheduler/sched-nice-design.txt che parla delle carenze (probabilmente quelle che hai descritto) e di come sono state corrette. – Alex

2

Si può avere uno sguardo a questa libreria (scritto da uno studente sulla mia, non ancora rilasciato, guardare il repository svn): https://sourceforge.net/projects/threadutility/

In sostanza, egli ha scritto un wrapper del boost :: filo che consente di specificare e impostare le priorità dei thread in modo portatile, selezionando la corretta implementazione interna a seconda della piattaforma (attualmente Linux o Windows). In Linux, il codice usa syscall sched_setscheduler().

1

boost::thread ha la capacità di acquisire attributi pthread prima che venga chiamato pthread_create(). Fornisce il tipo boost::thread::attributes, che a sua volta può essere utilizzato solo per impostare le dimensioni dello stack (sui sistemi che lo supportano), ma presenta anche un metodo .get_native_handle(), che restituisce un pthread_attr_t, su cui è possibile impostare gli attributi desiderati. È quindi sufficiente chiamare make_thread() con l'oggetto boost::thread::attributes come argomento. Vedere la seconda e terza casella di codice in questa sezione: http://www.boost.org/doc/libs/1_53_0/doc/html/thread/thread_management.html#thread.thread_management.tutorial.attributes

+0

Quindi, per riassumere, 'boost :: thread' non fornisce un modo per impostare la priorità e si consiglia di utilizzare la soluzione esatta di cui l'OP ha parlato nella sua domanda? –

+0

La differenza è se si impostano gli attributi prima o dopo aver chiamato 'pthread_create'. Per i documenti che ho collegato 'boost :: thread' in modo esplicito non è possibile salvare questo tramite gli handle nativi. Qui stiamo ottenendo l'handle nativo sugli attributi, quindi possiamo impostarli prima che ci sia anche un handle pthread. – tiberious726

+0

Nella sua domanda, dice che fa attualmente: 'pthread_attr_setschedparam (myThread.native_handle(), SCHED_RR, & param);' Quindi questo è quello che suggerisci non è vero? –

Problemi correlati