優先級反轉我試圖挑起優先級反轉上演示的目的一個小C++程序但我不能:持有互斥不搶佔低優先級線程並繼續在關鍵部分運行。這是我在做什麼:不能挑起C++
// let's declare a global mutex
pthread_mutex_t my_mutex;
...
int main(int argc, char **argv) {
...
pthread_t normal_thread;
pthread_t prio_thread;
pthread_mutexattr_t attr;
pthread_mutexattr_init (&attr);
pthread_mutexattr_setprotocol (&attr, PTHREAD_PRIO_NONE); // ! None !
pthread_mutex_init(&my_mutex, &attr);
// create first normal thread (L):
pthread_create(&normal_thread, NULL, the_locking_start_routine, NULL);
// just to help the normal thread enter in the critical section
sleep(2);
// now will launch:
// * (M) several CPU intensive SCHED_FIFO threads with priority < 99
// * (H) one SCHED_FIFO thread that will try to lock the mutex, with priority < 99
// build Real Time attributes for the Real Time threads:
pthread_attr_t my_rt_att;
pthread_attr_init(&my_rt_att);
// it was missing in the original post and it was also wrong:
// even setting the SchedPolicy you have to set "InheritSched"
pthread_attr_setinheritsched(&my_rt_att, PTHREAD_EXPLICIT_SCHED)
pthread_attr_setschedpolicy(&my_rt_att, SCHED_FIFO);
struct sched_param params;
params.sched_priority = 1;
pthread_attr_setschedparam(&my_rt_att, ¶ms);
pthread_create(&prio_thread, &my_rt_att, the_CPU_intensive_start_routine, NULL)
params.sched_priority = 99;
pthread_attr_setschedparam(&my_rt_att, ¶ms);
// create one RealTime thread like this:
pthread_create(&prio_thread, &my_rt_att, the_locking_start_routine, NULL) //coma was missing
...
}
void *the_locking_start_routine(void *arg) {
...
pthread_mutex_lock(&my_mutex);
// This thread is on the critical section
// ... (skipped)
pthread_mutex_unlock(&my_mutex);
...
}
...但它不工作,我不能有我想要的優先倒置。
這是發生了什麼:
據我瞭解,有喜歡的Linux的CFS一個scheduller,非實時線程(SCHED_OTHER)將不會運行,直到沒有任何實時線程(SCHED_FIFO或SCHED_RR)在奔跑狀態。但我已經達到了這個線程同時運行:
- (L)一個非實時(SCHED_OTHER)線程鎖定互斥體和 消耗CPU
- (M)幾個實時線程(SCHED_FIFO,&優先> 0)CPU 密集型和非等待鎖定互斥
- (H)一個實時線程(SCHED_FIFO,&最高優先級)等待 的鎖
還有更多的實時CPU密集線程(M)運行的比我的系統的CPU數量更多......但非實時線程持有(L)鎖仍然佔用CPU並完成它的工作並釋放互斥鎖之前「M」線程完成消耗CPU。
爲什麼低優先級的線程不被搶佔,應用程序是否被鎖定,我無法獲得優先級反轉?
我在內核2.6.38-13的Ubuntu Desktop 11.04上使用g ++ 4.5.2。
請顯示the_start_routine的所有代碼。我看不出它在鎖定和解鎖之間做了什麼。也在關鍵部分之外 - 大概有一個循環在某處變成了點?如果它在CS內部,爲什麼它會被搶佔 - 這是唯一準備好/正在運行的線程,因爲所有其他線程都停留在互斥鎖上。 – 2012-03-19 23:22:25
接下來的回答(無論是否)大多數現代調度程序都具有反死鎖保護措施,可以在一個或多個時間片段中改變優先級,以防止優先級反轉導致死鎖,當檢測到或被認爲合適時。無論您使用的是哪種調度程序,Linux都無法確定。但是,如果你還沒有,請注意這一點。 – 2012-03-20 15:17:51
嗨@天使,你爲什麼設置PTHREAD_PRIO_NONE而不是PTHREAD_PRIO_INHERIT? – ransh 2015-10-03 20:20:34