linux c进程资源

2018-06-14 21:21:52

每个进程都会消耗诸如内存和CPU时间之类的系统资源,本文将介绍与资源相关的系统调用。

#include <sys/resource.h>

int getrusage(int who, struct rusage *res_usage);

//Returns 0 on success, or –1 on error

getrusage() 系统调用返回调用进程或子进程用掉的各类系统资源统计信息,利用此函数,父进程可以监控子进程cpu和内存的使用量。

who参数可以指定为以下:

RUSAGE_SELF 返回调用进程相关信息。
RUSAGE_CHILDREN 返回调用进程的所有被终止和处于等待状态的子进程相关信息。
RUSAGE_THREAD 返回调用线程相关信息。

rusage结构定义如下,不懂英文的可以参考这篇文章对一些资源的文字解释 linux命令date、time

struct rusage {
    struct timeval ru_utime; /* User CPU time used */
    struct timeval ru_stime; /* System CPU time used */
    long ru_maxrss; /* Maximum size of resident set (kilobytes)
                    [used since Linux 2.6.32] */
    long ru_ixrss; /* Integral (shared) text memory size
                    (kilobyte-seconds) [unused] */
    long ru_idrss; /* Integral (unshared) data memory used
                    (kilobyte-seconds) [unused] */
    long ru_isrss; /* Integral (unshared) stack memory used
                    (kilobyte-seconds) [unused] */
    long ru_minflt; /* Soft page faults (I/O not required) */
    long ru_majflt; /* Hard page faults (I/O required) */
    long ru_nswap; /* Swaps out of physical memory [unused] */
    long ru_inblock; /* Block input operations via file
                    system [used since Linux 2.6.22] */
    long ru_oublock; /* Block output operations via file
                    system [used since Linux 2.6.22] */
    long ru_msgsnd; /* IPC messages sent [unused] */
    long ru_msgrcv; /* IPC messages received [unused] */
    long ru_nsignals; /* Signals received [unused] */
    long ru_nvcsw; /* Voluntary context switches (process
                    relinquished CPU before its time slice
                        expired) [used since Linux 2.6] */
    long ru_nivcsw; /* Involuntary context switches (higher
                    priority process became runnable or time
                    slice ran out) [used since Linux 2.6] */
};

进程资源限制

每个进程都用一组资源限制值,它们可以用来限制进程能够消耗的各种系统资源。shell的内置命令ulimit可以设置shell的资源限制。用shell创建的进程会继承这些限制。

linux下的/proc/PID/limits文件可以查看任意进程的所有资源限制。

#比如我的其中一个进程显示如下
[root@izj6cfw9yi1iqoik31tqbgz c]# cat /proc/1841/limits 
Limit                     Soft Limit           Hard Limit           Units     
Max cpu time              unlimited            unlimited            seconds   
Max file size             unlimited            unlimited            bytes     
Max data size             unlimited            unlimited            bytes     
Max stack size            8388608              unlimited            bytes     
Max core file size        0                    unlimited            bytes     
Max resident set          unlimited            unlimited            bytes     
Max processes             3895                 3895                 processes 
Max open files            65535                65535                files     
Max locked memory         65536                65536                bytes     
Max address space         unlimited            unlimited            bytes     
Max file locks            unlimited            unlimited            locks     
Max pending signals       3895                 3895                 signals   
Max msgqueue size         819200               819200               bytes     
Max nice priority         0                    0                    
Max realtime priority     0                    0                    
Max realtime timeout      unlimited            unlimited            us

下面2个系统调用用来读取和修改自己的资源限制

#include <sys/resource.h>

struct rlimit {
    rlim_t rlim_cur; /* Soft limit (actual process limit) */
    rlim_t rlim_max; /* Hard limit (ceiling for rlim_cur) */
};

int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);

//Both return 0 on success, or –1 on error

软限制 规定了进程能够消耗的数量。一个进程可以将软限制调整为从0到硬限制之间的值。对于大多数资源来讲,硬限制 的唯一作用是为软限制设定上限。特权进程能够增大或缩小硬限制(必须大于软限制),非特权进程则能缩小硬限制(不可逆)。rlim_cur和 rlim_max 取值为RLIM_INFINITY 表示没有限制。

resource的取值如下:

资源  限制
RLIMIT_AS 进程虚拟内存限制大小-字节
RLIMIT_CORE 核心文件大小-字节
RLIMIT_CPUCPU时间-s
RLIMIT_DATA 进程数据段-字节
RLIMIT_FSIZE 文件大小-字节
RLIMIT_MEMLOCK 锁住的内存-字节
RLIMIT_MSGQUEUE 为真实用户id分配posix消息队列-字节
RLIMIT_NICE nice值
RLIMIT_NOFILE 最大文件描述符+1
RLIMIT_NPROC 真实用户id下的进程数量
RLIMIT_RSS 
RLIMIT_RTPRIO 实时调度策略
RLIMIT_RTTIME 实时cpu时间 - 微妙
RLIMIT_SIGPENDING 真实用户id信号队列中的信号数
RLIMIT_STACK 栈段的大小

例子

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <pthread.h>

#include <sys/resource.h>

int printRlimit(const char *msg, int resource);

int printRlimit(const char *msg, int resource){
    struct rlimit rlim;

    if (getrlimit(resource, &rlim) == -1)
        return -1;

    printf("%s soft=", msg);
    if (rlim.rlim_cur == RLIM_INFINITY)
        printf("infinite");
#ifdef RLIM_SAVED_CUR           /* Not defined on some implementations */
    else if (rlim.rlim_cur == RLIM_SAVED_CUR)
        printf("unrepresentable");
#endif
    else
        printf("%lld", (long long) rlim.rlim_cur);

    printf("; hard=");
    if (rlim.rlim_max == RLIM_INFINITY)
        printf("infinite\n");
#ifdef RLIM_SAVED_MAX           /* Not defined on some implementations */
    else if (rlim.rlim_max == RLIM_SAVED_MAX)
        printf("unrepresentable");
#endif
    else
        printf("%lld\n", (long long) rlim.rlim_max);

    return 0;
}

int main(int argc, char *argv[]){
    struct rlimit rl;
    int j;
    pid_t childPid;

    if (argc < 2 || argc > 3 || strcmp(argv[1], "--help") == 0){
        printf("%s soft-limit [hard-limit]\n", argv[0]);
        return 1;
    }

    printRlimit("Initial maximum process limits: ", RLIMIT_NPROC);

    rl.rlim_cur = (argv[1][0] == 'i') ? RLIM_INFINITY : atoi(argv[1]);
    rl.rlim_max = (argc == 2) ? rl.rlim_cur :
                (argv[2][0] == 'i') ? RLIM_INFINITY : atoi(argv[2]);
    if (setrlimit(RLIMIT_NPROC, &rl) == -1)
        perror("setrlimit");

    printRlimit("New maximum process limits:     ", RLIMIT_NPROC);
    
    //在这里尽可能多的创建进程
    //return 0;
    for (j = 1; ; j++) {
        switch (childPid = fork()) {
        case -1: perror("fork");

        case 0: _exit(EXIT_SUCCESS);            /* Child */

        default:        /* Parent: display message about each new child
                           and let the resulting zombies accumulate */
            printf("Child %d (PID=%ld) started\n", j, (long) childPid);
            break;
        }
    }
}
#先切换成普通用户
[root@izj6cfw9yi1iqoik31tqbgz c]# su nobody
bash-4.2$ ./a.out 10 20
Initial maximum process limits:  soft=3895; hard=3895
New maximum process limits:      soft=10; hard=20
Child 1 (PID=21364) started
Child 2 (PID=21365) started
Child 3 (PID=21366) started
Child 4 (PID=21367) started
fork: Resource temporarily unavailable

上面显示只创建了4个子进程,这是因为nobody已经有6个进程


备注
1.编译器版本gcc4.8,运行环境centos7 64位
2.原文地址http://www.freecls.com/a/2712/59

©著作权归作者所有
收藏
推荐阅读
  • err
    linux c使用syslog记录消息

    syslog 工具提供了一个集中式日志工具,系统中的所有应用程序都可以使用这个记录日志消息。如下图syslogd 从两个不同的源接收日志消息:一个是unix domain...

  • linux c进程调度-CPU亲和力

    进程切换 CPU 时对性能会有一定的影响:如果在原来的 CPU 的高速缓冲器中存在进程的数据,那么为了将进程的一行数据加载进新 CPU 的高速缓冲器中,首先必须使这行数据失效(即在没被修改的情况下丢弃...

  • err
    linux c线程(2)-同步和线程取消

    本篇将介绍线程用来同步彼此行为的两个工具:互斥量和条件变量。我们先来看一个例子。#include &lt;sys/types.h&gt; #include &lt;std...

  • err
    linux c线程(1)-基础

    与进程类似,线程是允许应用程序并发执行多个任务的一种机制。一个进程可以包含多个线程。线程间共享同一份全局内存区域,其中包括初始化数据段,未初始化数据段,堆内存。传统uni...

  • err
    linux c程序的执行

    执行新程序:execve系统调用 execve() 可以将新程序加载到某一进程的内存空间。进程的栈、数据段、堆都会被新程序的相应部件所替换。由fork() 生成的子进程对...

  • nginx模块 ngx_http_headers_module

    ngx_http_headers_module 模块是用来增加 Expires 和 Cache-control,或者是任意的响应头。Syntax: add_header name value [alw...

  • nginx模块 ngx_http_gunzip_module、ngx_http_gzip_module、ngx_http_gzip_static_module

    ngx_http_gunzip_module 模块将文件解压缩后并在响应头加上 "Content-Encoding: gzip" 返回给客户端。为了解决客户端不支持gzip压缩。编译的时候带上 --w...

  • nginx模块 ngx_http_flv_module、ngx_http_mp4_module

    ngx_http_flv_module模块提供了对 flv 视频的伪流支持。编译的时候带上 --with-http_flv_module。它会根据指定的 start 参数来指定跳过多少字节,并在返回数...

  • nginx模块 ngx_http_fastcgi_module

    ngx_http_fastcgi_module 模块使得nginx可以与 fastcgi 服务器通信。比如目前要使得 nginx 支持 php 就得使用 fastcgi技术,在服务器上装上 nginx...

  • nginx模块 ngx_http_autoindex_module

    ngx_http_autoindex_module 模块可以将uri以 / 结尾时,列出里面的文件和目录。Syntax: autoindex on | off; Default: autoindex ...

简介
天降大任于斯人也,必先苦其心志。