スケジューリングの設定とプライオリティ逆転の回避法
赤松 エイト [著] 2008/01/30 14:00

サンプルファイル 35.00 KB

pthreadはPOSIX仕様に基づくOSにおける非同期処理の仕組みです。他の非同期処理と比較すると新しい仕組みですが、その奥は深くさまざまな機能を持っています。本稿ではスレッドのスケジューリング調整法とその影響、プライオリティ逆転の回避策を解説します。

1 2 3 4 →

はじめに

 この連載ではUNIX系OSなどで使われるスレッド「pthread」についてサンプルを交えて説明していきます。pthreadはPOSIXが仕様化したスレッドモデルです。サンプルはCと一部C++、調査環境はFedora 8(2.6.23.1-49.fc8)、32bit、glibc-4.1-2、gcc-4.1.2-33およびFedora Core 6(2.6.18-1.2798.fc6)、32bit、glibc-2.5-3、gcc-4.1.1-30を使用しています。

前回の記事

9. スケジューリング(リファレンス)

 LinuxやWindowsに代表されるOSは、複数の実行可能状態のスレッドやプロセスに対し、何らかの基準で実行すべき対象を選び、プロセスおよびスレッドを実行しています。いわゆるスケジューリングと言われている機能ですが、スレッドやプロセスはOSに対して明示的にスケジューリングを依頼するためのインターフェースを備えています。そのインターフェースを使用する事で、一部のスレッドに対して他スレッドと比べて優先的に処理を行うよう指示することができ、逆に全スレッドに対して平等に動作させる事もできます。

 しかしOSの仕事に対して明示的に指示する機能なので一部例外もあるものの、、当機能は特権を持つユーザーにのみ使用が許可されています。また、初期のLinuxカーネルにはスケジューリングがちゃんとサポートされていなかったようです。

 下記マクロを参照する事で自環境にスケジューリングがサポートされているか確認できます。

マクロ動作
_POSIX_PRIORITY_SCHEDULINGプロセスに対しスケジューリングが可能か
_POSIX_THREAD_PRIORITY_SCHEDULINGスレッドに対しスケジューリングが可能か
_POSIX_THREAD_PRIO_PROTECTプライオリティ最高限度mutexが利用可能か
_POSIX_THREAD_PRIO_INHERITプライオリティ継承mutexが利用可能か
#include <stdio.h>
#include <unistd.h>
#ifdef _POSIX_PRIORITY_SCHEDULING
#error "_POSIX_PRIORITY_SCHEDULING defined"
#else
#error "_POSIX_PRIORITY_SCHEDULING not defined"
#endif
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
#error "_POSIX_THREAD_PRIORITY_SCHEDULING defined"
#else
#error "_POSIX_THREAD_PRIORITY_SCHEDULING not defined"
#endif
#ifdef _POSIX_THREAD_PRIO_PROTECT
#error "_POSIX_THREAD_PRIO_PROTECT defined"
#else
#error "_POSIX_THREAD_PRIO_PROTECT not defined"
#endif
#ifdef _POSIX_THREAD_PRIO_INHERIT
#error "_POSIX_THREAD_PRIO_INHERIT defined"
#else
#error "_POSIX_THREAD_PRIO_INHERIT not defined"
#endif

 スレッドの場合、スケジューリングを行うにはスレッドを生成する際に属性を付加する事で対応できます。スレッド属性およびその初期化方法については8章を参照してください。

 スケジューリングはプライオリティおよびポリシーで決定されます。まずは関数リファレンスを、それ以降でプライオリティやポリシーの詳細を述べていきます。

9.1 リファレンス

 主にスレッド属性の設定にかかわる関数は下記の通りです。より詳細についてはmanコマンドを参照してください。

  • int pthread_attr_getschedparam( const pthread_attr_t * attr, struct sched_param * param );
    • pthread_attr_getschedparam:現在設定されているスケジューリングパラメータを取得できます。
    • pthread_attr_t:初期化済みのスレッド属性オブジェクト。
    • struct sched_param * param:スケジューリング用のパラメータを取得する領域。構造体ですが、私の環境ではメンバは int sched_priorityのみです。
  • int pthread_attr_setschedparam( pthread_attr_t *attr, const struct sched_param *param);
    • pthread_attr_setschedparam:スケジューリングパラメータを設定します。
  • int sched_get_priority_max(int policy);
    • sched_get_priority_max:ポリシーにおける最大プライオリティを取得します。
  • int sched_get_priority_min(int policy);
    • sched_get_priority_min:ポリシーにおける最小プライオリティを取得します。
  • int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
    • pthread_attr_setschedpolicy:新しいポリシーを設定します。
    • policy:SCHED_FIFO / SCHED_RR / SCHED_OTHERのみ取ります。
  • int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);
    • pthread_attr_getschedpolicy:現時点でのポリシーを取得します。
  • int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit);
    • pthread_attr_setinheritsched:親プロセスのスケジューリングパラメータを引き継ぐか、新規で競っているか
    • inherit:親スレッドおよび親プロセスのスケジューリングパラメータを継承するか新規で割り付けるかを指定します。PTHREAD_INHERIT_SCHED / PTHREAD_EXPLICIT_SCHEDのみ取ります。

プロフィール
赤松 エイト エイト

(株)DTSに勤てます。
WebアプリやJavaやLL等の上位アプリ環境を密かに憧れつつも、ず~っとLinuxとかHP-UXばかり、ここ数年はカーネル以上アプリ未満のあたりを行ったり来たりしています。
mixiもやってまして、こちらは子育てとか日々の日記メインです。


記事へのコメント・トラックバック機能は2011年6月に廃止させていただきました。記事に対する反響はTwitterやFacebook、ソーシャルブックマークサービスのコメントなどでぜひお寄せください。

スポンサーサイト