2009-09-25 17 views
25

Las bibliotecas Boost no parecen tener un dispositivo para establecer la prioridad de un subproceso. ¿Sería este el mejor código para usar en Linux o hay un método mejor?Establecimiento de prioridad de subprocesos en Linux con Boost

boost::thread myThread(MyFunction()); 

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

No tengo mucha experiencia en programación de Linux.

+0

Arafangion: ¿Tiene algo que respaldar? La página del manual de linux para pthread_attr_setschedparam dice que funciona. Además, mi experiencia personal es que funciona exactamente como está documentado. –

Respuesta

22

Esa es la plantilla básica de cómo lo haría, pero después de buscar no encontré ejemplos de código, así que creo que el veredicto es si es mejor o no.

El problema es que impulso :: hilo no tiene un constructor que permite a los atributos para ser aprobada en la creación del hilo en pthead lo que tiene que hacer cambios después de que el hilo se inicia. La única otra manera que conozco para solucionarlo es a través de la herencia de proceso/programación de hilos. A menos que se indique lo contrario, los hilos nuevos heredarán el cronograma/prioridad de su creador para que pueda cambiar el hilo actual antes de crear los hilos de trabajo y luego cambiarlos si lo desea. Parece incómodo, pero es una alternativa.

Aquí hay un truco de un ejemplo que con suerte demuestra ambos. Es posible que deba cambiar la política y la prioridad según corresponda y ejecutar como root.

Tenga cuidado con la forma de establecer la prioridad. Se aplican varias restricciones.

#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

Estaba buscando una muestra rápida para no pasar por las páginas del manual y me pareció útil. Gracias. –

+0

En comparación con 'boost :: thread'' QThread' realmente brilla en el departamento de poder establecer fácilmente la prioridad de subprocesos. – rbaleksandar

+0

Funciona perfecto con 'std :: thread' también. – ollo

1

No creo que Linux realmente tiene prioridades de los hilos - en la mayoría de los núcleos se pueden utilizar niveles 'agradable', pero eso es probablemente por ello (lo que simplificaría el programador) - Sin embargo, no todos los sistemas Linux respeto eso! (Depende del planificador).

+0

esta respuesta no se corresponde con lo que he visto o escuchado sobre Linux. ¿Tal vez te estás refiriendo a una versión anterior? – Alex

+0

@Alex: ¿Qué has escuchado? Es muy probable que me refiera a una versión anterior, o una concepción errónea de una versión anterior. – Arafangion

+0

la respuesta aceptada demuestra el establecimiento de las prioridades de subprocesos y la programación en Linux, por lo que Linux tiene implementadas las prioridades de subprocesos. En cuanto a los niveles de Niza encontré la documentación: http: //git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/tree/Documentation/scheduler/sched-nice-design.txt que habla sobre las deficiencias (probablemente las que usted describió) y cómo se han solucionado. – Alex

2

Puede echar un vistazo a esta biblioteca (escrito por un estudiante en la mía, no publicado aún, mirar el repositorio SVN): https://sourceforge.net/projects/threadutility/

Básicamente, él escribió un envoltorio del impulso :: hilo que permite especificar y establecer las prioridades de los hilos de manera portátil, seleccionando la implementación interna correcta según la plataforma (actualmente Linux o Windows). En Linux, el código usa el syscall sched_setscheduler().

1

boost::thread tiene la capacidad de admitir atributos pthread antes de llamar al pthread_create(). Proporciona el tipo boost::thread::attributes, que solo se puede usar para establecer el tamaño de pila (en los sistemas que lo admiten), pero también presenta un método .get_native_handle(), que devuelve pthread_attr_t, en el que puede establecer los atributos que desee. A continuación, puede simplemente llamar al make_thread() con ese objeto boost::thread::attributes como argumento. Consulte los cuadros de códigos segundo y tercero en esta sección: http://www.boost.org/doc/libs/1_53_0/doc/html/thread/thread_management.html#thread.thread_management.tutorial.attributes

+0

Entonces, para resumir, 'boost :: thread' no proporciona una manera de establecer la prioridad y ¿aconseja utilizar la solución exacta que el OP habló en su pregunta? –

+0

La diferencia es si configura los atributos antes o después de llamar a 'pthread_create'. De acuerdo con los documentos que he vinculado 'boost :: thread' explícitamente no permite este guardar a través de los identificadores nativos. Aquí obtenemos el manejo nativo de los atributos, por lo que podemos configurarlos incluso antes de que haya un manejador pthread. – tiberious726

+0

En su pregunta, dice que actualmente lo hace: 'pthread_attr_setschedparam (myThread.native_handle(), SCHED_RR, y param);' Así que eso es lo que sugiere ¿no es así? –

Cuestiones relacionadas