2009-09-25 81 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