带有SCHED_OTHER的可移植的pthread_setschedparam

我正在为我正在开发的项目组build一个Unix / Linux半可移植的线程类(即使用pthread库)。 部分项目需要能够设置某些线程的优先级,以允许同一进程中的其他线程更多的CPU时间; 这是pthread_setschedparam函数进来的地方,而我的类碰到了一堵砖墙。

下面是一个简单的testing,我把它放在一起来说明我的问题:

 #include <iostream> #include <unistd.h> #include <pthread.h> #include <sched.h> #include <string.h> #include <errno.h> pthread_mutex_t m_mtx; bool m_goahead; void dosleep(int millis) { usleep(millis*1000); } void domsg(const char *msg) { pthread_mutex_lock(&m_mtx); std::cout << msg << std::endl; pthread_mutex_unlock(&m_mtx); } void dowait() { while (!m_goahead) { dosleep(1); } } void *fn1(void *param) { domsg("in fn1...waiting"); dowait(); while (m_goahead) { dosleep(1000); domsg("in fn1 loop"); } } void *fn2(void *param) { domsg("in fn2...waiting"); dowait(); while (m_goahead) { dosleep(1000); domsg("in fn2 loop"); } } int main(int argc, char **argv) { // min prio = -2, max prio = 2 int t1_pri = 2, t2_pri = 0, main_pri = 1; //SCHED_RR, SCHED_FIFO, SCHED_OTHER (POSIX scheduling policies) int sched = SCHED_OTHER; // standard // get the range between min and max and set the priorities base on split range int min = sched_get_priority_min(sched); int max = sched_get_priority_max(sched); int skip = (max - min) / 5; // 5 since -2...2 struct sched_param main_param, t1_param, t2_param; memset(&main_param, 0, sizeof(sched_param)); memset(&t1_param, 0, sizeof(sched_param)); memset(&t2_param, 0, sizeof(sched_param)); main_param.sched_priority = (min + ((main_pri+2) * (skip+1))) + (skip / 2); t1_param.sched_priority = (min + ((t1_pri+2) * (skip+1))) + (skip / 2); t2_param.sched_priority = (min + ((t2_pri+2) * (skip+1))) + (skip / 2); std::cout << "main thread will have a prio of " << main_param.sched_priority << std::endl; std::cout << "t1 thread will have a prio of " << t1_param.sched_priority << std::endl; std::cout << "t2 thread will have a prio of " << t2_param.sched_priority << std::endl; m_goahead = false; pthread_mutex_init(&m_mtx, NULL); pthread_t t1, t2; // Create the threads if (pthread_create(&t1, NULL, fn1, NULL) != 0) { std::cout << "couldn't create t1" << std::endl; return -1; } if (pthread_create(&t2, NULL, fn2, NULL) != 0) { std::cout << "couldn't create t2" << std::endl; return -1; } dosleep(1000); // sleep a second before setting priorities // --main thread-- if (pthread_setschedparam(pthread_self(), sched, &main_param) != 0) { std::cout << "error setting priority for main thread: (" << errno << "), " << strerror(errno) << std::endl; } // --t1 thread-- if (pthread_setschedparam(t1, sched, &t1_param) != 0) { std::cout << "error setting priority for T1: (" << errno << "), " << strerror(errno) << std::endl; } // --t2 thread-- if (pthread_setschedparam(t2, sched, &t2_param) != 0) { std::cout << "error setting priority for T2: (" << errno << "), " << strerror(errno) << std::endl; } m_goahead = true; // all start // loop until user interupt for (;;) { dosleep(1000); domsg("in main loop"); } pthread_mutex_destroy(&m_mtx); return 0; } 

基于这个代码,如果我编译并在OpenBSD系统上运行它,我会得到以下结果:

 main thread will have a prio of 24 t1 thread will have a prio of 31 t2 thread will have a prio of 17 in fn1...waiting in fn2...waiting in fn1 loop in main loop in fn2 loop in fn1 loop in main loop in fn2 loop in fn1 loop in main loop in fn2 loop 

注意它如何按照线程优先级fn1,main,fn2的顺序进行…

如果我在Ubuntu 10.04LTS系统上运行这个相同的testing,我会得到以下结果:

 main thread will have a prio of 3 t1 thread will have a prio of 4 t2 thread will have a prio of 2 in fn1...waiting in fn2...waiting error setting priority for main thread: (22), Invalid argument error setting priority for T1: (22), Invalid argument error setting priority for T2: (22), Invalid argument in main loop in fn2 loop in fn1 loop in main loop in fn2 loop in fn1 loop in main loop in fn2 loop in fn1 loop 

我知道这个无效的参数是因为我指定了SCHED_OTHER优先级,并试图给它分配0以外的任何数字; 我无法确定的是我怎样才能使这个工作正常?

我试着'假设'一个SCHED_FIFOSCHED_RR优先级来获得最小/最大值,这使我有效的最小/最大值,我没有得到'无效参数'错误,但function循环输出不在优先级顺序,而是以函数发生调用的顺序(如果没有设置优先级,则可以预期)。

理想情况下,我会得到当前进程的优先级,然后分配该类上的线程,但是,如果当前进程的优先级是SCHED_OTHER然后设置一个线程的基础上产生了我不想要的无效结果。

有更多的“便携”方式来设置线程的优先级或获取有效的最小/最大值? 我甚至可以在某些环境下在SCHED_OTHER下设置一个线程的优先级,还是这个function留给了这个环境?

我在这个问题上陷入僵局,希望能够向正确的方向发展。

谢谢,请让我知道如果我的代码/解释不清楚。

如果有助于增进了解,请参阅此处。 但是,我学到了什么,SCHED_OTHER只是意味着所有的非实时线程将具有同等的优先级。 但是后来在提到BSD的时候给了max和min 0和99甚至在SCHED_OTHER的情况下,不明白为什么,但是有一点是很清楚的,它不是一个非常便携,依靠它的确切值就无济于事。 在这种情况下,进行特殊的处理会更好,比如范围是[0-0],然后使用nice(如果线程的优先级可以很好的固定,请让我知道)来设置优先级。

谢谢