2009-09-25 9 views
25

Die Boost-Bibliotheken scheinen kein Gerät zum Festlegen der Priorität eines Threads zu haben. Wäre dies der beste Code unter Linux oder gibt es eine bessere Methode?Einstellung der Thread-Priorität in Linux mit Boost

boost::thread myThread(MyFunction()); 

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

Ich habe nicht viele Linux-Programmiererfahrung.

+0

Arafangion: Haben Sie etwas, um das zu untermauern? Die Linux-Manpage für pthread_attr_setschedparam sagt, es funktioniert. Auch meine persönliche Erfahrung ist, dass es genauso funktioniert wie dokumentiert. –

Antwort

22

Das ist die grundlegende Vorlage für, wie ich es tun würde, aber nach der Suche habe ich fast keine Code Beispiele gefunden, so denke ich, das Urteil ist aus, ob es das Beste ist oder nicht.

Das Problem ist, dass boost :: thread keinen Konstruktor hat, der das Übergeben von Pthead-Attributen bei der Erstellung von Threads erlaubt, so dass Sie nach dem Start des Threads Änderungen vornehmen müssen. Der einzige andere Weg, den ich kenne, ist die Vererbung von Prozessen/Threads. Sofern nicht anders angegeben, erben neue Threads den Zeitplan/die Priorität ihres Erstellers, sodass Sie den aktuellen Thread ändern können, bevor Sie Worker-Threads erstellen, und dann bei Bedarf zurückwechseln können. Scheint umständlich, aber es ist eine Alternative.

Hier ist ein Hack ein Beispiel, das hoffentlich beide demostrates. Gegebenenfalls müssen Sie die Richtlinie und die Priorität ändern und als root ausführen.

Vorsicht Sie die Priorität, mit der Art und Weise eingestellt. Es gelten verschiedene Einschränkungen.

#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

Ich war nur auf der Suche nach einer schnellen Probe nicht durch manuelle Seiten zu gehen und fand das nützlich. Vielen Dank. –

+0

Im Vergleich zu 'boost :: thread' scheint' QThread' in der Tat in der Lage zu sein, die Threadpriorität einfach einstellen zu können. – rbaleksandar

+0

Funktioniert auch mit 'std :: thread'. – ollo

1

Ich glaube nicht, Linux hat wirklich Thread-Prioritäten - in den meisten Kernel Sie ‚Nice‘ Ebene verwenden können, aber das ist wohl darüber (der den Scheduler vereinfachen würde) - jedoch nicht alle Linux-Systeme werden respektiere das! (Abhängig vom Scheduler).

+0

Diese Antwort entspricht nicht dem, was ich über Linux gesehen oder gehört habe. Vielleicht beziehst du dich auf eine frühere Version? – Alex

+0

@Alex: Was hast du gehört? Es ist sehr wahrscheinlich, dass ich mich auf eine frühere Version oder eine falsche Vorstellung einer früheren Version beziehe. – Arafangion

+0

Die akzeptierte Antwort demonstriert das Setzen von Thread-Prioritäten und Scheduling unter Linux, so dass Linux Thread-Prioritäten implementiert hat. In Bezug auf die Nizza-Ebenen fand ich die Dokumentation: http: //git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/tree/Dokumentation/scheduler/sched-nice-design.txt die über die Mängel (wahrscheinlich die, die Sie beschrieben haben) und wie sie behoben wurden. – Alex

2

Sie einen Blick auf dieser Bibliothek haben kann (von einem Schüler auf Mine geschrieben, noch nicht veröffentlicht, Blick auf der SVN-Repository): https://sourceforge.net/projects/threadutility/

Grundsätzlich schrieb er einen Wrapper der boost :: Thread, ermöglicht es, die Prioritäten von Threads auf portable Weise festzulegen und festzulegen, indem die richtige interne Implementierung abhängig von der Plattform (derzeit Linux oder Windows) ausgewählt wird. In Linux verwendet der Code den syscall sched_setscheduler().

1

boost::thread hat die Fähigkeit, Pthread-Attribute vor pthread_create() aufgerufen wird. Es stellt den Typ boost::thread::attributes bereit, der selbst nur zum Festlegen der Stapelgröße (auf Systemen, die dies unterstützen) verwendet werden kann, aber auch eine .get_native_handle() Methode, die eine pthread_attr_t zurückgibt, auf der Sie Ihre gewünschten Attribute festlegen können. Sie können dann einfach make_thread() mit dem Objekt boost::thread::attributes als Argument aufrufen. Siehe die zweite und dritte Code-Box in diesem Abschnitt: http://www.boost.org/doc/libs/1_53_0/doc/html/thread/thread_management.html#thread.thread_management.tutorial.attributes

+0

Zusammenfassend bietet "boost :: thread" keine Möglichkeit, die Priorität festzulegen, und Sie raten, die genaue Problemumgehung zu verwenden, über die das OP in seiner Frage gesprochen hat? –

+0

Der Unterschied besteht darin, ob Sie die Attribute vor oder nach dem Aufruf von 'pthread_create' setzen. Für die Dokumente, die ich verlinkt habe, erlaubt boost :: thread explizit nicht das Speichern über die nativen Handles. Hier erhalten wir das native Handle für die Attribute, so dass wir sie festlegen können, bevor es überhaupt ein Pthread-Handle gibt. – tiberious726

+0

In seiner Frage sagt er, dass er gerade tut: 'pthread_attr_setschedparam (myThread.native_handle(), SCHED_RR, & param);' Also das ist, was Sie vorschlagen, nicht wahr? –

Verwandte Themen