Go to main content
リソース管理および Oracle® Solaris ゾーン開発者ガイド

印刷ビューの終了

更新: 2016 年 11 月
 
 

リソース制御のコード例

リソース制御のマスター監視プロセス

次の例は、マスターオブザーバプロセスです。図 5 は、マスター監視プロセスのリソース制御を示しています。


注 - /etc/project ファイル内の行ブレークは無効です。行ブレークは、印刷されるページまたは表示されるページ上に例を表示するためだけにここに示されています。/etc/project ファイル内の各エントリは個別の行に記述する必要があります。

図 5  マスター監視プロセス

image:図は、マスター監視プロセスのリソース制御を示しています。

この例の重要なポイントは次のとおりです。

  • タスクの制限には特権が付与されているため、アプリケーションは制限を変更したり、シグナルなどのアクションを指定したりできません。マスタープロセスは、同じリソース制御を基本リソース制御としてタスク上に確立することでこの問題を解決します。マスタープロセスは、リソース上の同じ値またはわずかに少ない値を、異なるアクション (シグナル = XRES) で使用します。マスタープロセスはこのシグナルを待機するスレッドを作成します。

  • rctlblk は不透明です。構造体は動的に割り当てる必要があります。

  • スレッドを作成する前に、sigwait(2) の要求に応じてすべてのシグナルがブロックされることに注意してください。

  • スレッドはシグナルをブロックするために sigwait(2) を呼び出します。sigwait() が SIGXRES シグナルを返すと、スレッドがマスタープロセスの子に通知し、これによって使用する LWP 数の削減に適応します。それぞれの子についても、1 つの子に 1 つのスレッドが入った状態で同様にモデル化し、このシグナルを待機して、そのプロセスの LWP 使用率に適切に適応するようにしてください。

rctlblk_t *mlwprcb;
sigset_t smask;

/* Omit return value checking/error processing to keep code sample short */
/* First, install a RCPRIV_BASIC, v=1000, signal=SIGXRES rctl */
mlwprcb = calloc(1, rctlblk_size());	 /* rctl blocks are opaque: */
       rctlblk_set_value(mlwprcb, 1000);
       rctlblk_set_privilege(mlwprcb, RCPRIV_BASIC);
       rctlblk_set_local_action(mlwprcb, RCTL_LOCAL_SIGNAL, SIGXRES);
       if (setrctl("task.max-lwps", NULL, mlwprcb, RCTL_INSERT) == -1) {
           perror("setrctl");
           exit (1);
       }

/* Now, create the thread which waits for the signal */
        sigemptyset(&smask);
        sigaddset(&smask, SIGXRES);
        thr_sigsetmask(SIG_BLOCK, &smask, NULL);
thr_create(NULL, 0, sigthread, (void *)SIGXRES, THR_DETACHED, NULL));

/* Omit return value checking/error processing to keep code sample short */

void *sigthread(void *a)
{
        int sig = (int)a;
        int rsig;
        sigset_t sset;

        sigemptyset(&sset);
        sigaddset(&sset, sig);

        while (1) {
                 rsig = sigwait(&sset);
          if (rsig == SIGXRES) {
              notify_all_children();
              /* e.g. sigsend(P_PID, child_pid, SIGXRES); */
		     }
        }
}

特定のリソース制御の値-アクションペアをすべて表示

次の例では、特定のリソース制御 task.max-lwps の値-アクションペアがすべて一覧表示されています。この例の重要なポイントは、getrctl(2) が 2 つのリソース制御ブロックを取り、RCTL_NEXT フラグのリソース制御ブロックを返すことです。すべてのリソース制御ブロックを繰り返し処理するには、ここに示すように rcb_tmp rctl ブロックを使用してリソース制御ブロックの値を繰り返しスワップします。

rctlblk_t *rcb1, *rcb2, *rcb_tmp;
	...
/* Omit return value checking/error processing to keep code sample short */
rcb1 = calloc(1, rctlblk_size()); /* rctl blocks are opaque: */
                               /* "rctlblk_t rcb" does not work */
rcb2 = calloc(1, rctlblk_size());
getrctl("task.max-lwps", NULL, rcb1, RCTL_FIRST);
while (1) {
     print_rctl(rcb1);
     rcb_tmp = rcb2;
     rcb2 = rcb1;
     rcb1 = rcb_tmp;        /* swap rcb1 with rcb2 */
     if (getrctl("task.max-lwps", rcb2,  rcb1, RCTL_NEXT) == -1) {
          if (errno == ENOENT) {
               break;
     } else {
          perror("getrctl");
          exit (1);
     }
     }
}

project.cpu-shares の設定と新しい値の追加

この例の重要なポイントは次のとおりです。

この例ではプロジェクトの CPU 配分割り当て (project.cpu-shares) を取得し、その値を nshares に変更します。

/* Omit return value checking/error processing to keep code sample short */
blk1 = malloc(rctlblk_size());
getrctl("project.cpu-shares", NULL, blk1, RCTL_FIRST);
my_shares = rctlblk_get_value(blk1);
printout_my_shares(my_shares);
/* if privileged, do the following to */
/* change project.cpu-shares to "nshares" */
blk1 = malloc(rctlblk_size());
blk2 = malloc(rctlblk_size());
if (getrctl("project.cpu-shares", NULL, blk1, RCTL_FIRST) != 0) {
     perror("getrctl failed");
     exit(1);
}
bcopy(blk1, blk2, rctlblk_size());
rctlblk_set_value(blk1, nshares);
if (setrctl("project.cpu-shares", blk2, blk1, RCTL_REPLACE) != 0) {
     perror("setrctl failed");
     exit(1);
}		     

リソース制御ブロックを使用して LWP 制限を設定

次の例では、超えることのできない 3000 LWP の特権付き制限をアプリケーションが設定しています。さらに、アプリケーションは 2000 LWP の基本制限も設定しています。この制限を超えると、SIGXRES がアプリケーションに送信されます。SIGXRES を受け取るとアプリケーションがすぐにその子プロセスに通知を送信し、次にその子プロセスが、使用するまたは必要となる LWP 数を減らす場合があります。

/* Omit return value and error checking */

#include <rctl.h>

rctlblk_t *rcb1, *rcb2;

/*
         * Resource control blocks are opaque
         * and must be explicitly allocated.
         */
rcb1 = calloc(rctlblk_size());	

rcb2 = calloc(rctlblk_size());	


/* Install an RCPRIV_PRIVILEGED, v=3000: do not allow more than 3000 LWPs */
rctlblk_set_value(rcb1, 3000);
rctlblk_set_privilege(rcb1, RCPRIV_PRIVILEGED);
rctlblk_set_local_action(rcb1, RCTL_LOCAL_DENY);
setrctl("task.max-lwps", NULL, rcb1, RCTL_INSERT);


/* Install an RCPRIV_BASIC, v=2000 to send SIGXRES when LWPs exceeds 2000 */
rctlblk_set_value(rcb2, 2000);
rctlblk_set_privilege(rcb2, RCPRIV_BASIC);
rctlblk_set_local_action(rcb2, RCTL_LOCAL_SIGNAL, SIGXRES);
setrctl("task.max-lwps", NULL, rcb2, RCTL_INSERT);