Solaris 10 资源管理器开发者指南

资源控制代码示例

资源控制的主观察进程

以下示例是主观察者进程。图 5–3 显示了主观察进程的资源控制。


注 –

换行符在 /etc/project 文件中是无效的。此处显示的换行符仅允许示例显示在列显页或显示页上。/etc/project 文件中的每一项都必须占用单独的一行。


图 5–3 主观察进程

显示主观察进程的资源控制的图

该示例的要点包括以下内容:

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) 使用两个资源控制块,并返回 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);