The process needs certain resources such as CPU and memory to perform the tasks. Now we will look into the related commands and system calls to know the information on resource utilization and monitoring. Also there are certain limits by default for each process on the resources, and if required the limits can be enhanced to accommodate the application requirements.
Following are the essential system or process resources information using commands −
$ top
The top command continuously displays the usage of system resources. If any process puts the system in some kind of hang state (consuming more of CPU or Memory) it is possible to note the process information and take appropriate action (such as killing the related process).
$ ps
The ps command provides information about all the running processes. This helps to monitor and control the processes.
$ vmstat
The vmstat command reports the statistics of virtual memory subsystem. It reports the information of processes (waiting to run, sleeping, runnable processes, etc.), memory (virtual memory information such as free, used, etc.), swap area, IO devices, system information (number of interrupts, context switches) and CPU (user, system and idle time).
$ lsof
The lsof command prints the list of open files of all the current running processes, including system processes.
$ getconf –a
The getconf command displays the system configuration variables information.
Now, let us take a look at the related system calls.
System call getrusage(), which provides information on system resource usage.
System calls related to accessing and setting resource limits viz., getrlimit(), setrlimit(), prlimit().
#include <sys/time.h> #include <sys/resource.h> int getrusage(int who, struct rusage *usage);
The system call getrusage() returns the information on the system resource usage. This can include information on self, children, or calling thread using flags RUSAGE_SELF, RUSAGE_CHILDREN, RUSAGE_THREAD for the “who” variable. After the call, it returns the information in the structure rusage.
This call would return “0” on success and “-1” on failure.
Let us look at the following sample program.
#include<stdio.h> #include<sys/time.h> #include<sys/resource.h> void main(void) { struct rusage res_usage; int retval; retval = getrusage(RUSAGE_SELF, &res_usage); if (retval == -1) { perror("getrusage error"); return; } printf("Details of getrusage:\n"); printf("User CPU time (seconds) is %d\n", (int)res_usage.ru_utime.tv_sec); printf("User CPU time (micro seconds) is %d\n", (int)res_usage.ru_utime.tv_usec); printf("Maximum size of resident set (kb) is %ld\n", res_usage.ru_maxrss); printf("Soft page faults (I/O not required) is %ld\n", res_usage.ru_minflt); printf("Hard page faults (I/O not required) is %ld\n", res_usage.ru_majflt); printf("Block input operations via file system is %ld\n", res_usage.ru_inblock); printf("Block output operations via file system is %ld\n", res_usage.ru_oublock); printf("Voluntary context switches are %ld\n", res_usage.ru_nvcsw); printf("Involuntary context switches are %ld\n", res_usage.ru_nivcsw); return; }
Details of getrusage: User CPU time (seconds) is 0 User CPU time (micro seconds) is 0 Maximum size of resident set (kb) is 364 Soft page faults (I/O not required) is 137 Hard page faults (I/O not required) is 0 Block input operations via file system is 0 Block output operations via file system is 0 Voluntary context switches are 0 Involuntary context switches are 1
Let us now look at the system calls related to accessing and setting resource limits.
#include <sys/time.h> #include <sys/resource.h> int getrlimit(int resource, struct rlimit *rlim); int setrlimit(int resource, const struct rlimit *rlim); int prlimit(pid_t pid, int resource, const struct rlimit *new_limit, struct rlimit *old_limit);
The system call getrlimit() gets the resource limits in structure rlimit by inputting the resource one needs such as RLIMIT_NOFILE, RLIMIT_NPROC, RLIMIT_STACK, etc.
The system call setrlimit() sets the resource limits as mentioned in the rlimit structure as far as within the limits.
The system call prlimit() is used for varius purposes, such as either for retrieving the current resource limits or for updating the resource limits to new values.
The structure rlimit contains two values −
Soft limit − Current limit
Hard limit − Maximum limit to which it can be extended.
RLIMIT_NOFILE − Returns the maximum number of file descriptors that can be opened by this process. For example, if it returns 1024, then the process has file descriptors from 0 to 1023.
RLIMIT_NPROC − Maximum number of processes that can be created for a user of that process.
RLIMIT_STACK − The maximum size in bytes of the stack segment for that process.
All these calls would return “0” on success and “-1” on failure.
Let us consider the following example where we are using getrlimit() system call.
#include<stdio.h> #include<sys/time.h> #include<sys/resource.h> void main(void) { struct rlimit res_limit; int retval; int resources[] = {RLIMIT_NOFILE, RLIMIT_NPROC, RLIMIT_STACK}; int max_res; int counter = 0; printf("Details of resource limits for NOFILE, NPROC, STACK are as follows: \n"); max_res = sizeof(resources)/sizeof(int); while (counter < max_res) { retval = getrlimit(resources[counter], &res_limit); if (retval == -1) { perror("getrlimit error"); return; } printf("Soft Limit is %ld\n", res_limit.rlim_cur); printf("Hard Limit (ceiling) is %ld\n", res_limit.rlim_max); counter++; } return; }
Details of resource limits for NOFILE, NPROC, STACK are as follows: Soft Limit is 516 Hard Limit (ceiling) is 516 Soft Limit is 256 Hard Limit (ceiling) is 256 Soft Limit is 33554432 Hard Limit (ceiling) is 33554432
Let us consider another example with getrlimit() system call but now with prlimit() system call.
#include<stdio.h> #include<unistd.h> #include<sys/time.h> #include<sys/resource.h> void main(void) { struct rlimit res_limit; int retval; int resources[] = {RLIMIT_NOFILE, RLIMIT_NPROC, RLIMIT_STACK}; int max_res; int counter = 0; printf("Details of resource limits for NOFILE, NPROC, STACK using prlimit are as follows: \n"); max_res = sizeof(resources)/sizeof(int); while (counter < max_res) { retval = prlimit(getpid(), resources[counter], NULL, &res_limit); if (retval == -1) { perror("prlimit error"); return; } printf("Soft Limit is %ld\n", res_limit.rlim_cur); printf("Hard Limit (ceiling) is %ld\n", res_limit.rlim_max); counter++; } return; }
Details of resource limits for NOFILE, NPROC, STACK using prlimit are as follows: Soft Limit is 516 Hard Limit (ceiling) is 516 Soft Limit is 256 Hard Limit (ceiling) is 256 Soft Limit is 33554432 Hard Limit (ceiling) is 33554432