使用Boost在Linux中设置线程优先级

时间:2009-09-25 23:21:43

标签: c++ linux boost pthreads posix

Boost Libraries似乎没有设置线程优先级的设备。这是在Linux上使用的最佳代码还是有更好的方法?

boost::thread myThread( MyFunction() );

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

我没有很多Linux编程经验。

4 个答案:

答案 0 :(得分:24)

这是我如何做的基本模板,但在搜索后我发现旁边没有代码示例,所以我猜测判断是否是最好的。

问题是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;
}

答案 1 :(得分:2)

你可以看看这个库(由我的学生编写,尚未发布,请查看svn存储库): https://sourceforge.net/projects/threadutility/

基本上,他编写了一个boost :: thread的包装器,它允许以可移植的方式指定和设置线程的优先级,方法是根据平台(目前是Linux或Windows)选择正确的内部实现。在Linux中,代码使用sched_setscheduler()系统调用。

答案 2 :(得分:2)

boost::thread确实能够在调用pthread_create()之前接受pthread属性。它提供了类型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

答案 3 :(得分:1)

我认为Linux确实没有线程优先级 - 在大多数内核中你可以使用'Nice'级别,但这可能是关于它的(这将简化调度程序) - 但是,并非所有Linux系统都会尊重它! (取决于调度程序)。