Establecer la prioridad de subprocesos en Linux con Boost


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

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 Linux.

Author: Newton Falls, 2009-09-26

4 answers

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

El problema es que boost::thread no tiene un constructor que permita que los atributos pthead se pasen en la creación del hilo, por lo que debe realizar cambios después de que se inicie el hilo. La única otra forma que conozco de sortear eso es a través de la herencia de programación de procesos/subprocesos. A menos que se indique lo contrario, los subprocesos heredarán la programación / prioridad de su creador para que pueda cambiar el subproceso actual antes de crear subprocesos de trabajo y luego volver a cambiar si lo desea. Parece incómodo, pero es una alternativa.

Aquí hay un hack 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 en que establece 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;
}
 23
Author: Duck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-11 21:21:52

Puede echar un vistazo a esta biblioteca (escrita por un estudiante en la mía, aún no publicada, mire el repositorio svn): https://sourceforge.net/projects/threadutility /

Básicamente, escribió un wrapper de boost::thread que permite especificar y establecer las prioridades de los hilos de una manera portátil, seleccionando la implementación interna correcta dependiendo de la plataforma (actualmente Linux o Windows). En Linux, el código usa la llamada sched_setscheduler ().

 2
Author: knulp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-05 09:48:44

boost::thread tiene la capacidad de tomar atributos pthread antes de que se llame a pthread_create(). Proporciona el tipo boost::thread::attributes, que a su vez solo se puede usar para establecer el tamaño de la pila (en sistemas que lo soportan), pero el objeto attributes también presenta un método .get_native_handle(), que devuelve un pthread_attr_t, en el que puede establecer los atributos deseados. A continuación, puede simplemente llamar a make_thread() con ese objeto boost::thread::attributes como argumento. Vea el segundo y tercer cuadro de código en esta sección: http://www.boost.org/doc/libs/1_53_0/doc/html/thread/thread_management.html#thread.thread_management.tutorial.attributes

 2
Author: tiberious726,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-01 15:55:16

No creo que Linux realmente tenga prioridades de subprocesos - en la mayoría de los kernels puedes usar niveles 'Agradables', pero eso es probablemente (lo que simplificaría el planificador) - sin embargo, ¡no todos los sistemas linux respetarán eso! (Depende del programador).

 1
Author: Arafangion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-27 22:21:18