デモンストレーションの目的で小さな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 のようなスケジューラでは、実行中の状態のリアルタイム スレッド (SCHED_FIFO または SCHED_RR) がなくなるまで、非リアルタイム スレッド (SCHED_OTHER) は実行されません。しかし、私はこのスレッドを同時に実行することを達成しました:
- (L) ミューテックスをロックし、CPU を消費する 1 つの非リアルタイム (SCHED_OTHER) スレッド
- (M) 複数のリアルタイム スレッド (SCHED_FIFO 、および優先順位 > 0) CPU を集中的に使用し、mutex のロックを待機していない
- (H) 1 つのリアルタイム スレッド (SCHED_FIFO 、および最高の優先度) がロックを待機中
私のシステムのCPUの量よりも多くのリアルタイムCPU集中スレッド(M)が実行されています...しかし、ロックを保持している非リアルタイムスレッド(L)はまだCPUを消費しており、作業を終了し、ミューテックスを解放します「M」スレッドが CPU の消費を終了します。
優先度の低いスレッドがプリエンプトされず、アプリケーションがデッドロックされ、優先度の逆転が得られないのはなぜですか?
カーネル 2.6.38-13 を搭載した Ubuntu デスクトップ 11.04 で g++ 4.5.2 を使用しています。