From: Yusuke ENDOH Date: 2008-01-15T21:56:00+09:00 Subject: [ruby-dev:33124] Thread#priority= does not work 遠藤と申します。 Thread#priority= による優先度の設定ができないようです。 以下は Thread#priority= のコメントに書いてあるサンプルコードですが、 コメントの通りに動きません。 $ ./ruby -ve ' count1 = count2 = 0 a = Thread.new do loop { count1 += 1 } end a.priority = -1 b = Thread.new do loop { count2 += 1 } end b.priority = -2 sleep 1 p count1 #=> 622504 p count2 #=> 5832 ' ruby 1.9.0 (2008-01-15 revision 0) [i686-linux] 3196560 3359563 Thread#priority= の実現に pthread の優先度を使う戦略のようですが、 これには問題があると思います。 - pthread のデフォルトのスケジューリングアルゴリズム (SCHED_OTHER) は 優先度を無視する - 優先度を考慮してくれるスケジューリング (SCHED_RR と SCHED_FIFO) は スーパーバイザ権限がないと使えないらしい (少なくとも LInux では) このような制約がある以上、pthread の優先度を使うのは難しいと思います。 解決方法を 2 つ提案します。 (1) Thread#priority= を deprecated する (2) native_thread_yield するときは priority の数だけ繰り返して 擬似的に優先度を実現する 以下は (2) の実装イメージです。thread_win32 はとりあえず無視してます。 Index: thread.c =================================================================== --- thread.c (revision 15066) +++ thread.c (working copy) @@ -676,13 +676,16 @@ thread_debug("rb_thread_schedule\n"); if (!rb_thread_alone()) { rb_thread_t *th = GET_THREAD(); + int priority = th->priority; thread_debug("rb_thread_schedule/switch start\n"); rb_gc_save_machine_context(th); native_mutex_unlock(&th->vm->global_interpreter_lock); { - native_thread_yield(); + while(priority++ < 0) { + native_thread_yield(); + } } native_mutex_lock(&th->vm->global_interpreter_lock); ついでですが、仮に pthread の優先度がうまく使えたとしても、現在の native_thread_apply_priority は min/max のチェックがなんか変な 気がします。 Index: thread_pthread.c =================================================================== --- thread_pthread.c (revision 15066) +++ thread_pthread.c (working copy) @@ -355,12 +355,12 @@ max = sched_get_priority_max(policy); min = sched_get_priority_min(policy); - if (min < priority) { + if (min > priority) { + priority = min; + } + else if (max < priority) { priority = max; } - else if (max > priority) { - priority = min; - } sp.sched_priority = priority; pthread_setschedparam(th->thread_id, policy, &sp); -- Yusuke ENDOH