以下示例是主观察者进程。图 5–3 显示了主观察进程的资源控制。
换行符在 /etc/project 文件中是无效的。此处显示的换行符仅允许示例显示在列显页或显示页上。/etc/project 文件中的每一项都必须占用单独的一行。
该示例的要点包括以下内容:
由于任务的限制具有权限,因此应用程序无法更改限制,也无法指定操作(如信号)。主进程通过为任务建立与基本资源控制相同的资源控制解决了此问题。主进程对资源使用相同的值或稍小的值,但执行不同的操作(信号 = XRES)。主进程将创建一个线程以等待此信号。
rctlblk 是不透明的。需要动态分配结构。
请注意,sigwait(2) 要求在创建线程之前阻塞所有的信号。
线程将调用 sigwait(2) 来阻塞信号。如果 sigwait() 返回 SIGXRES 信号,则线程将通知主进程的子进程适当减少正在使用的 LWP 的数目。此外,还应该使用每个子进程中的线程以类似方式为每个子进程建模,以等待此信号并适当调整其进程的 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); */ } } }