2010-07-08 129 views
6

我需要管理具有不同優先級的線程池,所以我寫了下面的線程啓動程序:並行線程與實時優先級

static 
int startup(thrd_t *thrd, thrd_sync_t *sync, int prio) 
{ 
    pthread_attr_t attr; 
    int err; 
    struct sched_param param = { 
     .sched_priority = prio 
    }; 

    assert(pthread_attr_init(&attr) == 0); 
    assert(pthread_attr_setschedpolicy(&attr, SCHED_FIFO) == 0); 
    assert(pthread_attr_setschedparam(&attr, &param) == 0); 
    err = pthread_create(&thrd->handler, &attr, thread_routine, (void *)thrd); 
    pthread_attr_destroy(&attr); 

    return err; 
} 

原則上,非特權用戶不應該被允許執行代碼:由於運行具有高優先級的線程的安全隱患,pthread_create()調用應該返回EPERM。

意外的是它對普通用戶有效,但它根本不尊重給定的優先級。

我試着通過去除pthread_attr_t,並通過一旦線程已經創建設置調度屬性修改代碼:

static 
int startup(thrd_t *thrd, thrd_sync_t *sync, int prio) 
{ 
    pthread_attr_t attr; 
    int err; 
    struct sched_param param = { 
     .sched_priority = prio 
    }; 

    err = pthread_create(&thrd->handler, NULL /*&attr*/, thread_routine, 
         (void *)thrd); 
    if (err != 0) return err; 

    err = pthread_setschedparam(thrd->handler, SCHED_FIFO, &param); 
    if (err != 0) return err; 

    return err; 
} 

這種方法的方式是更難以管理,因爲在的情況下,錯誤我需要殺死新創建的線程。至少它似乎在權限要求方面正常工作(只有root可以執行此操作),但仍不優先考慮優先級。

我做錯了什麼?

EDIT

我剛加入其由每一個線程執行的下面的代碼段:

static 
void getinfo() 
{ 
    struct sched_param param; 
    int policy; 

    sched_getparam(0, &param); 
    DEBUG_FMT("Priority of this process: %d", param.sched_priority); 

    pthread_getschedparam(pthread_self(), &policy, &param); 

    DEBUG_FMT("Priority of the thread: %d, current policy is: %d and should be %d", 
       param.sched_priority, policy, SCHED_FIFO); 
} 

與第一種方法(即pthread_attr_t方法)事實證明,所述pthread_attr_setschedpolicy由於優先級爲0且策略不是SCHED_FIFO,因此完全無效。

使用第二種方法(即pthread_setschedparam方法),該函數會打印預期數據,但執行會以錯誤的方式運行。

+1

你如何確定呼叫不被尊重?我遇到過類似的情況,但API沒有實現,因此失敗。 – Ioan 2010-07-08 19:56:48

+0

@Ioan:查看問題的更新版本。 – Dacav 2010-07-08 20:17:10

+1

OT:不要在'assert()'中放置代碼。如果這是用斷言禁用編譯的,代碼將不會被執行。 – bstpierre 2010-07-15 17:04:03

回答

8

我認爲你也必須使用pthread_attr_setinheritsched來確保你對優先級設置的改變被考慮在內。從手冊頁:

PTHREAD_INHERIT_SCHED 指定調度策略和相關屬性 從創建 線程繼承,並調度在此ATTR參數屬性 是要 忽略。

PTHREAD_EXPLICIT_SCHED 指定的調度策略和關聯屬性是 被設置爲從該屬性對象中的相應值 。

一點點手冊頁進一步您有:

的繼承,調度的屬性的默認設置在新 初始化線程屬性對象PTHREAD_INHERIT_SCHED。

+0

它的工作!非常感謝:這解決了兩個問題之一。然而,這很違反直覺:如果我指定優先級,可能是因爲我想讓你使用它,對吧? :)現在我會找到錯誤行爲的原因:也許是一個錯誤? – Dacav 2010-07-08 21:39:03

+0

@Dacav:你能否詳述一下你的第二個問題?不知道我得到它。該領域的錯誤(但你自己;-)是不太可能的。你沒有多說你正在運行的系統,但是現在線程實現每天都經過了數十億次的測試。 – 2010-07-08 21:44:52

+0

目前我的程序只是一個腳手架:真正的業務邏輯應該稍後添加。爲了測試每個線程的優先級,首先通過等待一個條件變量來啓動,該條件變量隨後被廣播。然後每個線程不斷在stderr上寫假。我期望的是在優先級較低的線程之前觀看更高優先級的線程'虛假'。我懷疑我的雙核心是出乎意料的交錯的原因......我現在想着一個很好的測試。 – Dacav 2010-07-08 21:59:16