《APUE》笔记-第七章-进程环境

时间:2022-11-12 04:26:03

1.引言

重要知识:命令行参数、环境变量(环境指针、环境表、环境字符串)、进程终止方式、c程序的启动和终止、c程序的存储空间布局、setjmp、longjmp、进程资源限制

2.main函数

int main(int argc, char *argv[]);//有 argv[argc] = NULL;

执行一个新程序的过程:bash->fork()->子shell->exec()->装入新程序,所以,当执行一个新程序时,调用exec的进程(即子shell)将命令行参数传给新程序;


3.进程终止

8种终止方式,其中5种正常、3种异常。

#include <stdlib.h>

void exit(int status);

void _Exit(int status);

#include <unistd.h>

void _exit(int status);

其中status:终止状态(退出状态)

调用exit和调用_exit、_Exit区别:

调用_exit和_Exit会直接返回内核;调用exit会先执行终止处理程序,再执行fclose清理缓冲区,最后通过调用_exit或_Exit返回内核


调用atexit来登记终止处理程序

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

成功,0;失败,非0

练习atexit、exit:

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

void atexit_func1(void)
{
printf("this is atexit_func1\n");
}

void atexit_func2(void)
{
printf("this is atexit_func2\n");
}

void atexit_func3(void)
{
printf("this is atexit_func3\n");
}

int main()
{
printf("this is in main()\n");
atexit(atexit_func1);
atexit(atexit_func3);
atexit(atexit_func2);
atexit(atexit_func2);
exit(0);
}
结果:
《APUE》笔记-第七章-进程环境

分析:每登记一次,执行一次;登记顺序与执行顺序相反。exit(0)中0是终止状态


4.c程序的启动和终止、c程序的存储空间布局

看书


5.内存分配函数malloc、calloc、realloc

void *malloc(size_t size);//size为总的分配的内存的大小,分配的内存未初始化

void *calloc(size_t nobj, size_t size);//size为每个对象大小,分配的内存每一bit都初始化为0

void *realloc(void *ptr, size_t newsize);//新增区域内初始值不确定

void *free(void *ptr);

程序练习:

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

int main()
{
char *p1 = (char *)malloc(sizeof(char) * 10);
if (p1 == NULL)
{
printf("malloc() error\n");
exit(0);
}
printf("memory from malloc() *p1 = %c\n", *p1);

int *p2 = (int *)calloc(20, sizeof(int));
if (p2 == NULL)
{
printf("calloc() error\n");
exit(0);
}
printf("memory from calloc() *p2 = %d\n", *p2);
printf("position: 0x%0x\n", p2);

int *p3 = (int *)realloc(p2, (20 + 100000) * sizeof(int));
if (p3 == NULL)
{
printf("realloc() error\n");
exit(0);
}
printf("memory from calloc() *p3 = %d\n", *p3);
printf("new position memory from calloc() *p3 = %d\n", *(p3 + 200));
printf("position: 0x%0x\n", p3);

free(p1);
free(p3);

exit(0);
}

结果:

《APUE》笔记-第七章-进程环境
分析:

malloc分配的内存初始值不确定;calloc分配的内存初始化为0;realloc分配的新内存初始值也为0?(和书上不同),当realloc新分配的内存过大时,会将整个内容移到另一个足够大的区域


6.环境变量

extern char **environ;

#include <stdlib.h>

char *getenv(const char *name);

int putenv(char *str);

成功,0;出错,非0

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

int unsetenv(const char *name);

成功,0;出错,-1

练习程序:

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

extern char **environ;

int main()
{
char **env = environ;
while (*env != NULL)//打印全部环境变量
{
printf("%s\n", *env);
env++;
}
char *name = getenv("HOME");//取环境变量
printf("HOME=%s\n", name);

if (putenv("MY_HOME=zxin") != 0)//设置环境变量及其值
{
printf("putenv() error\n");
}

if (setenv("id","000111", 0) != 0)//设置环境变量及其值

{
printf("setenv() error\n");
}
printf("MY_HOME=%s\n", getenv("MY_HOME"));
printf("id=%s\n", getenv("id"));
unsetenv("MY_HOME");//删除环境变量
unsetenv("id");

exit(0);
}
结果:

《APUE》笔记-第七章-进程环境
中间还有很大一部分省略,最后为:

《APUE》笔记-第七章-进程环境


7.setjmp和longjmp

#include <setjmp.h>

jmp_buf;

int setjmp(jmp_buf jmpbuffer);

void longjmp(jmp_buf jmpbuffer, int val);

longjmp的参数val为setjmp的返回值

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

jmp_buf buffer;

void func1(void);
void func2(void);
void func3(void);
void func4(void);

int main()
{
printf("now in main()\n");
if (setjmp(buffer) == 5)
{
printf("now return to main()\n");
exit(0);
}
func1();
exit(0);
}

void func1()
{
printf("now in func1\n");
func2();
}
void func2()
{
printf("now in func2\n");
func3();
}
void func3()
{
printf("now in func3\n");
func4();
}
void func4()
{
printf("now in func4\n");
longjmp(buffer, 5);
}
结果:

《APUE》笔记-第七章-进程环境

8.getrlimit、setrlimit

#include <sys/resource.h>

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

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

成功,0;出错,非0

struct rlimit

{

        rlim_t rlim_cur;//软限制

        rlim_t rlim_max;//硬限制

};

程序如下:

#include <stdio.h>
#include <sys/resource.h>

int main()
{
struct rlimit lim;
if (getrlimit(RLIMIT_NOFILE, &lim) != 0)//每个进程能打开的最多文件数
exit(-1);
if (lim.rlim_cur == RLIM_INFINITY)
printf("infinite\n");
else
printf("%d\n", lim.rlim_cur);
if (lim.rlim_max == RLIM_INFINITY)
printf("infinite\n");
else
printf("%d\n", lim.rlim_max);
exit(0);
}
结果:

《APUE》笔记-第七章-进程环境