chapter 7 UNIX进程的环境

来源:互联网 发布:家具画图软件 编辑:程序博客网 时间:2024/05/01 11:29

进程终止的方式:

1,正常终止:

       从main返回;

       调用exit;

       调用_exit;

2,异常终止:

       调用abort;

       由一个信号终止。

exit和_exit的差异:

#include <stdlib.h>

void exit(int status);

#include <unistd.h>

void _exit(int status);

其中,exit会先执行一些清理工作,而_exit则直接进入内核。


终止处理函数:exit handler

ANSI C规定,一个进程可以登记多至32个函数。

登记方法:

#include <stdlib.h>

int atexit(void (*func)(void));

exit会以登记顺序相反的顺序调用这些函数。


环境表

extern char** environ;

存取方法:

#include <stdlib.h>

char* getenv(const char* name);

int putenv(char* string);

int setenv(const char* name, const char* value, int overwrite);

int unsetenv(const char* name);

int clearenv(void);

设置环境变量的难点在于环境变量处于内存的顶端,需要增加空间的时候处理逻辑比较重要。如果需要内存的话就会把环境表移到堆中去。


c程序的存储空间布局

可以用size命令查看text,data,bss


共享库

减少了每个可执行文件的长度,但增加了一些运行时间开销。


存储器分配:

#include <stdlib.h>

void* malloc(size_t size);

void* calloc(size_t nobj, size_t size);

void* realloc(void* ptr, size_t size);

void* free(void* ptr);

大多数实现所分配的存储空间比所要求的要稍大一些,额外的空间用来记录管理信息----分配块的长度,指向下一个分配块的指针等等。如果写过一个已分配区的文段,则会改写后一块的管理信息,这种错误是灾难性的。

另一个致命错误是释放一个已经释放的块。

alloca函数在栈上分配空间,并自动释放:

#include <alloca.h>

void* alloca(size_t size);


非局部跳转----setjmp和longjmp函数。

非局部跳转表示在栈上跳过若干调用帧。

#include <setjmp.h>

int setjmp(jmp_buf env);

int longjmp(jmp_buf env, int val);

存放在存储器中的变量将具有longjmp时的值,而在CPU和浮点寄存器中的变量则恢复为调用setjmp时的值。

ex:

#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>

static void f1(int,int,int);
static void f2(void);

static jmp_buf jmpbuffer;

int main(void){
    int count;
    register int val;
    volatile int sum;

    count=2;
    val=3;
    sum=4;
    if(setjmp(jmpbuffer)!=0){
        printf("after longjmp:count=%d, val=%d, sum=%d\n",count,val,sum);
        exit(0);
    }
    count=97;
    val=98;
    sum=99;

    f1(count,val,sum);
}

static void f1(int i, int j, int k){
    printf("in f1():count=%d, val=%d, sum=%d\n",i,j,k);
    f2();
}

static void f2(void){
    longjmp(jmpbuffer,1);
}

结果:

hoperun@rh-ub063:/local/unix_environment$ gcc -O testjmp.c -o testjmp
hoperun@rh-ub063:/local/unix_environment$ testjmp
in f1():count=97, val=98, sum=99
after longjmp:count=2, val=3, sum=99
hoperun@rh-ub063:/local/unix_environment$ gcc testjmp.c -o testjmp
hoperun@rh-ub063:/local/unix_environment$ testjmp
in f1():count=97, val=98, sum=99
after longjmp:count=97, val=98, sum=99

资源限制:

规则:

1.任何一个进程都可将一个软限制更改为小于或等于其硬限制。

2.任何一个进程都可降低其硬限制值,但它必须大于或等于其软限制值。不可逆。

3.只有超级用户可以提高硬限制。

资源限制影响到调用进程并由其子进程继承。

#include <sys/time.h>

#include <sys/resource.h>

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

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


struct rlimit
  {
    /* The current (soft) limit.  */
    rlim_t rlim_cur;
    /* The hard limit.  */
    rlim_t rlim_max;
  };

例子:

#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <stdio.h>
#include <stdlib.h>

#define doit(name) pr_limits(#name,name);

static void pr_limits(char*, int);

int main(void){
    doit(RLIMIT_CORE);
    doit(RLIMIT_CPU);
    doit(RLIMIT_DATA);
    doit(RLIMIT_FSIZE);
    doit(RLIMIT_STACK);

    #ifdef RLIMIT_MEMLOCK
        doit(RLIMIT_MEMLOCK);
    #endif
    #ifdef RLIMIT_NOFILE
        doit(RLIMIT_NOFILE);
    #endif
    #ifdef RLIMIT_OFILE
        doit(RLIMIT_OFILE);
    #endif
    #ifdef RLIMIT_NPROC
        doit(RLIMIT_NPROC);
    #endif
    #ifdef RLIMIT_RSS
        doit(RLIMIT_RSS);
    #endif
    #ifdef RLIMIT_VMEM
        doit(RLIMIT_VMEM);
    #endif
    exit(0);
}

static void pr_limits(char* name, int resource){
    struct rlimit limit;

    if(getrlimit(resource, &limit)<0){
        printf("getrlimit error for %s", name);
    }
    printf("%-14s ",name);
    if(limit.rlim_cur == RLIM_INFINITY){
        printf("(infinity) ");
    }else{
        printf("%10ld ", limit.rlim_cur);
    }
    if(limit.rlim_max == RLIM_INFINITY){
        printf("(infinity)\n");
    }else{
        printf("%10ld\n", limit.rlim_max);
    }
}

unbuntu下执行结果:

hoperun@rh-ub063:/local/unix_environment$ gcc rlimittest.c -o rlimittest
hoperun@rh-ub063:/local/unix_environment$ rlimittest
RLIMIT_CORE             0 (infinity)
RLIMIT_CPU     (infinity) (infinity)
RLIMIT_DATA    (infinity) (infinity)
RLIMIT_FSIZE   (infinity) (infinity)
RLIMIT_STACK      8388608 (infinity)
RLIMIT_MEMLOCK      65536      65536
RLIMIT_NOFILE        1024       1024
RLIMIT_OFILE         1024       1024
RLIMIT_NPROC   (infinity) (infinity)
RLIMIT_RSS     (infinity) (infinity)
hoperun@rh-ub063:/local/unix_environment$

原创粉丝点击