Подтвердить что ты не робот

Установка приоритета потока в Linux с помощью Boost

У библиотек Boost нет устройства для установки приоритета потока. Будет ли это лучший код для использования в Linux или есть лучший метод?

boost::thread myThread( MyFunction() );

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

У меня нет опыта программирования в Linux.

4b9b3361

Ответ 1

Это базовый шаблон для того, как бы я это сделал, но после поиска я нашел рядом без примеров кода, поэтому, я думаю, вердикт о том, лучше ли это или нет.

Проблема заключается в том, что boost:: thread не имеет конструктора, который позволяет передавать атрибуты pthead при создании потока, поэтому вам нужно внести изменения после запуска потока. Единственный другой способ, который я знаю, чтобы обойти это, - это наследование процесса/потока. Если не указано иначе, новые потоки наследуют расписание/приоритет их создателя, поэтому вы можете изменить текущий поток перед созданием рабочих потоков, а затем, если хотите, изменить его. Кажется неудобным, но это альтернатива.

Вот взломать пример, который, мы надеемся, демонстрирует и то, и другое. Возможно, вам потребуется изменить политику и приоритет по мере необходимости и запустить с правами root.

Будьте осторожны с тем, как вы устанавливаете приоритет. Существуют различные ограничения.

#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

Вы можете взглянуть на эту библиотеку (написанную студентом по моему, еще не выпущенную, посмотрите на репозиторий svn): https://sourceforge.net/projects/threadutility/

В принципе, он написал обертку потока boost::, который позволяет определять и устанавливать приоритеты потоков переносимым способом, выбирая правильную внутреннюю реализацию в зависимости от платформы (в настоящее время Linux или Windows). В Linux код использует sched_setscheduler() syscall.

Ответ 3

Я не думаю, что Linux действительно имеет приоритеты потоков - в большинстве ядер вы можете использовать уровни "Nice", но это, вероятно, об этом (что упростит планировщик), однако не все системы Linux будут уважать это! (Зависит от планировщика).

Ответ 4

boost::thread имеет возможность принимать атрибуты pthread до вызова pthread_create(). Он предоставляет тип boost::thread::attributes, который сам может быть использован только для установки размера стека (в системах, которые его поддерживают), но также представляет метод .get_native_handle(), который возвращает pthread_attr_t, на котором вы можете установить желаемые атрибуты. Затем вы можете просто вызвать make_thread() с этим объектом boost::thread::attributes в качестве аргумента. Смотрите второй и третий коды кода в этом разделе: http://www.boost.org/doc/libs/1_53_0/doc/html/thread/thread_management.html#thread.thread_management.tutorial.attributes