现在的位置: 首页 > 综合 > 正文

《APUE 2e》学习笔记 第七章 进程环境

2014年02月03日 ⁄ 综合 ⁄ 共 3955字 ⁄ 字号 评论关闭

1. 八种进程终止方式:

    正常方式:

  A.从main返回。

       B.调用 exit。

       C.调用 _exit 或 _Exit 。

       D.最后一个线程从其启动例程返回。

       E.最后一个线程调用pthread_exit。

    异常方式:

       A.调用 abort。

       B.接到一个信号并终止。

       C.最后一个线程对取消请求做出响应。

 

2. exit 函数

   #include <stdlib.h>

   void exit(int status);

   void _Exit(int status);

   #include <unistd.h>

   void _exit(int status);

   exit执行一些清理工作。_Exit、_exit 立即进入内核。

 

3. 终止处理程序

   #include <stdlib.h>

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

                 Returns: 0 if OK,nonzero on error

   一个程序可登记多达32个终止处理程序,调用atexit来注册这些函数。

   exit调用这些终止处理函数的顺序与它们登记时候的顺序相反。

  
示例,
终止处理函数的注册与调用

#include <stdio.h>
#include <stdlib.h>
 
static void my_exit1(void)
{
    printf("first exit handler\n");
}
 
static void my_exit2(void)
{
    printf("second exit handler\n");
}
 
int main(void)
{
    if(atexit(my_exit2)!=0)
        fprintf(stderr,"can't register my_exit2\n");
    if(atexit(my_exit1)!=0)
        fprintf(stderr,"can't register my_exit1\n");
    if(atexit(my_exit1)!=0)
        fprintf(stderr,"can't register my_exit1\n");
 
    printf("main is done\n");
    return 12;
}

运行结果:

root@ubuntu1:~/apue/ch7# ./a.out

main is done

first exit handler

first exit handler

second exit handler

4. 命令行参数

示例,打印命令行参数

#include <stdio.h>
#include <stdlib.h>
 
int main(int argc,char *argv[])
{
    int i;
    for(i=0;i<argc;i++)   //可以换成 for(i=0;argv[i] !=NULL;i++)
        printf("argv[%d]:%s\n",i,argv[i]);
    exit(0);
}

运行结果:

root@ubuntu1:~/apue/ch7# ./a.out aaa bbb ccc

argv[0]:./a.out

argv[1]:aaa

argv[2]:bbb

argv[3]:ccc

5. 环境表

  extern char**environ;

  该全局变量指向环境表。

  示例,查看环境表

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

extern char **environ;
void main()
{
    int i;
    for(i=0;environ[i]!=NULL;i++)
        printf("%s\n",environ[i]);
}

6. 内存分配

#include <stdlib.h>

void *malloc(size_t size);

void *calloc(size_t nobj,size_t size);

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

                          All threereturn: non-null pointer if OK, NULL on error

void free(void *ptr);

malloc 初始值不确定。calloc空间每位初始化为0。

7.  环境变量的操作

#include <stdlib.h>

char *getenv(const char*name);

                 Returns: pointer tovalue associated with name, NULL if not found

int putenv(char *str);

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

int unsetenv(const char*name);

                 All return: 0 if OK,nonzero on error

getenv 获取指定环境变量的值。

unsetenv删除环境变量name的定义。

setenv 如果name已经存在,参数 rewrite,如果非0,则首先删除现有定义。若为0,这不删除其现有定义

setenv,putenv 都是设置环境变量,区别在于:

setenv必须分配存储区, copy环境变量数值到进程环境表。

而putenv并不copy环境变量数值到进程环境表,只是存放环境变量数值的指针。

8.  跨函数跳转

  #include <setjmp.h>

  int setjmp(jmp_buf
env);

                         Returns: 0if called directly, nonzero if returning from a call to longjmp

  void longjmp(jmp_buf
env, int val);

  示例,演示跨函数跳转

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
 
jmp_buf jmpbuffer;
 
int f2()
{
    printf("f2()\n");
    longjmp(jmpbuffer,3);
    return 0;
}
 
int f1()
{
    printf("f1()\n");
    f2();
    return 0;
}
 
void main()
{
    int jval;
    printf("main begin\n");
 
    if((jval=setjmp(jmpbuffer))!=0)
    {
        printf("jmp jval=%d\n",jval);
        exit(0);
    }

    f1();
    printf("main end\n");
}

运行结果:

root@ubuntu1:~/apue/ch7# ./a.out

main begin

f1()

f2()

jmp jval=3


9.  进程资源限制的查询和更改

   #include <sys/resource.h>

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

   int setrlimit(int resource, const structrlimit  *rlptr);

                          Bothreturn: 0 if OK, nonzero on error

   rlimit结构体定义:

    structrlimit {

         rlim_t rlim_cur;   /* soft limit: currentlimit */

         rlim_t rlim_max;   /* hard limit: maximumvalue for rlim_cur */

    }; 

  
修改资源限制的三条规则:

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

     B. 任何一个进程都可降低其硬限制值,但它必须大于或等于其软限制值。这种降低对于普通用户是不可逆的。

     C. 只有超级用户进程可以提高硬限制值。

 

示例,对RLIMIT_NOFILE限制资源的查询和设置。

#include <stdio.h>
#include <sys/resource.h>
 
void printf_limit()
{
    structrlimit limit;
    printf("get RLIMIT_NOFILE limit:\n");
    if(getrlimit(RLIMIT_NOFILE,&limit)!=0)
        fprintf(stderr,"getrlimit error\n");
 
    if(limit.rlim_cur==RLIM_INFINITY)
        printf("soft limit:infinite\n");
    else
        printf("soft limit:%ld\n",limit.rlim_cur);
 
    if(limit.rlim_max==RLIM_INFINITY)
        printf("hard limit:infinite\n");
    else
        printf("hard limit:%ld\n",limit.rlim_max);
}
 
void set_limit()
{
    structrlimit limit;
 
    printf("set soft limit =800\n");
    limit.rlim_cur=800;
    if(setrlimit(RLIMIT_NOFILE,&limit)!=0)
        fprintf(stderr,"setrlimit error\n");
}
 
void main()
{
    printf_limit();
    set_limit();
    printf_limit();
}

运行结果:

root@ubuntu1:~/apue/ch7# ./a.out

get RLIMIT_NOFILE limit:

soft limit:1024

hard limit:1024

set soft limit =800

get RLIMIT_NOFILE limit:

soft limit:800

hard limit:1024


抱歉!评论已关闭.