2009-09-25 56 views
25

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

boost::thread myThread(MyFunction()); 

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

我没有很多Linux编程经验。

+0

Arafangion:你有什么要支持的吗? pthread_attr_setschedparam的linux手册页说它可以工作。此外,我个人的经验是,它的工作原理与文件完全一致。 – 2011-11-18 07:10:46

回答

22

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

问题是,boost :: thread没有一个构造函数,它允许在创建线程时传递pthead属性,所以你必须在线程启动后进行更改。我知道解决这个问题的唯一方法是通过进程/线程计划继承。除非另有指示,否则新线程将继承其创建者的计划/优先级,以便在创建工作线程之前更改当前线程,然后如果需要则更改回来。看起来很尴尬,但它是一种选择。

下面是一个例子的破解,希望能够解释两者。您可能需要根据需要更改策略和优先级,并以根用户身份运行。

请注意您设置优先级的方式。各种限制适用。

#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

我只是想找一个快速样本不去谷槽手册页,发现这很有用。谢谢。 – 2011-08-12 13:05:06

+0

与'boost :: thread'相比''QThread'确实能够轻松设置线程优先级。 – rbaleksandar 2016-06-01 08:35:00

+0

与'std :: thread'完美搭配。 – ollo 2016-09-05 16:42:45

1

我不认为Linux的真正拥有线程的优先级 - 在大多数内核可以使用“好”的水平,但是这可能是它(这将简化调度) - 然而,并不是所有的Linux系统将尊重那! (取决于调度程序)。

+0

这个答案不符合我所看到或听说过的关于linux的内容。也许你指的是早期版本? – Alex 2013-07-18 08:01:28

+0

@亚历克斯:你听到了什么?这很可能是我指的是早期版本,或者是早期版本的错误概念。 – Arafangion 2013-07-18 08:03:13

+0

接受的答案演示了在linux下设置线程优先级和调度,以便linux确实实现了线程优先级。关于尼斯级别,我找到了文档:http://git.kernel。org/cgit/linux/kernel/git/next/linux-next.git/tree/Documentation/scheduler/sched-nice-design.txt它讨论了缺点(可能是你描述的缺点)以及它们是如何修复的。 – Alex 2013-07-19 14:05:21

2

你可以看看这个库(通过对矿井,尚未公布一个学生写的,看看svn库): https://sourceforge.net/projects/threadutility/

基本上,他写了升压的包装::线程允许通过根据平台(当前Linux或Windows)选择正确的内部实现来以便携方式指定和设置线程的优先级。在Linux中,代码使用sched_setscheduler()系统调用。

1

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

+0

所以总结一下,'boost :: thread'没有提供设置优先级的方法,你建议使用OP在他的问题中提到的确切的解决方法? – 2016-03-03 22:30:49

+0

区别在于您在调用'pthread_create'之前还是之后设置属性。根据我链接'boost :: thread'的文档显式不允许通过本地句柄保存。这里我们得到了属性的本地句柄,所以我们可以在它们之前设置它们,甚至是一个pthread句柄。 – tiberious726 2016-03-03 22:37:32

+0

在他的问题中,他说他目前的做法是:'pthread_attr_setschedparam(myThread.native_handle(),SCHED_RR,&param);' 所以这就是你所说的不是吗? – 2016-03-03 22:39:22