Linux_进程学习笔记

进程的终止函数

C程序的启动函数是main,也是进程代码的入口点;
main(int argc, char *argv[]);
argc:参数个数
argv[]:传入的参数表

当内核启动C程序时,会调用main函数前调用特殊的启动函数来获取main函数的地址和传递main函数的参数,并且将这些信息填写到进程控制块中。

正常终止:
(1)从main函数中返回
(2)在任意代码中调用
在这里插入图片描述

终止程序的2个exit函数:
(1)头文件stlib.h,函数定义:void exit(int status)
(2)头文件unistd.h,函数定义:void _exit(int status)
相同点:
调用这两个函数都会正常地终止一个进程
不同点:
_exit函数:调用_exit函数将会立即返回内核
exit函数:调用exit函数,会执行下面3个操作:
1)执行预先注册地终止处理函数
2)执行文件I/0操作地善后工作,使得所有缓冲地输出数据被更新到相应地设备
3)返回内核

return 与 exit地区别:
(1)reuan 是C语言地关键字,exit是POSIX API函数
(2)在main函数中,执行return和调用exit函数会产生相同地效果
(3)在子函数中,执行return仅仅从子函数中返回,而调用exit函数将会退出当前进程。

执行exit函数后地一些效应:
(1)当进程终止时,程序可能需要进行一些自身地清理工作,如日志登记、资源释放等;
(2)通过atexit函数或on_exit函数允许进程注册若干终止处理函数,当进程终止时,这些终止处理函数将会被自动调用。

注册终止处理函数:
(1)头文件stdlib.h

  1. int atexit(void(*func)(void));
  2. int on_exit(void(func)(int, void), void *arg)

(2)ABSI C规定一个进程最多只能注册32个终止处理函数
(3)当显示调用或隐含调用exit函数终止进程(从main中返回、最后一个线程退出等)将会回调这些注册终止处理函数(最先注册地函数最后被回调)
(4)显示调用_exit函数终止进程时将不会回调这些注册地终止函数

atexit例子:

void func1() {
	printf("func1 is called\n");
}
void func2() {
	printf("func2 is called\n");
}
void fun3() {
	printf("func3 is called\n");
}

int main(int argc, char **argv) {
	atexit(func1);
	atexit(func2);
	atexit(func3);
	printf("process exit\n");
	return 0;
}

程序运行效果:(感觉有点像栈)
在这里插入图片描述

on_exit列子:

void func1(int status, void *arg) {
	printf("func1 exit status is %d\n", status);
	printf("func1 arg is %d\n", *((int *)arg));
}
void func2(int status, void *arg) {
	printf("func2 exit status is %d\n", status);
	printf("func2 arg is %d\n", *((int *)arg));
}
void func3(int status, void *arg) {
	printf("func3 exit status is %d\n", status);
	printf("func3 arg is %d\n", *((int *)arg));
}

int i, j, k;
int main(int argc, char **argv) {
	i = 3; 
	on_exit(func1, (void *)&i);
	j = 4;
	on_exit(func2, (void *)&j);
	k = 5;
	on_exit(func3, (void *)&k);
	printf("process exit\n");
	return 0;
} 

运行效果:
在这里插入图片描述

进程的环境

进程内存空间布局
这里有两个,一个是进程的内核空间资源,一个是用户空间资源;’
在这里插入图片描述

用户空间:
正文:CPU执行的代码部分,正文段通常是共享、可读的。
数据段:

  1. 初始化的数据段:保研程序中需明确赋初值的变量,如全局变量int maxcount=99;
  2. 未初始化的数据段:程序执行之前,将此段中的数据初始化未0,如全局变量long sum[1000];

栈:主要用于支撑函数调用存放参数、局部变量等等

命令行参数:

  1. ls[参数]<路径或文件名>
  2. mkdir
  3. copy

例子:

#include <stdio.h>
int main(int argc, char ** argv) {
	int i;
	for(i = 0; i < argc; i ++)
		printf("Argument %d is %s.\n", i, argv[i]);
		return 0;
}

运行效果:
在这里插入图片描述

环境变量表:
环境变量是Linux系统所特有的;

  1. 每个进程都会自己的环境变量表

  2. 通过全局的环境执指针(environ)可以直接访问环境变量表(字符传数组)
    1)头文件:unistd.h
    2)extern char **environ;

  3. 环境变量字符串形式为"name = value",name是环境变量名称,value为环境变量赋值
    在这里插入图片描述

  4. 获取环境变量的方法
    1)直接通过environ变量访问环境表
    2)使用getenv函数

  5. getenv函数用于获取环境变量值
    1)头文件:stdlib.h
    2)char* getenv(const char *name)
    3)指定环境变量的名称,返回环境变量字符串指针,若未找到则返回空之指针

  6. 设置环境变量的三种方法
    1)putenv
    2)setenv
    3)unsetenv

  7. putenv函数将环境变量字符串放入环境变量表中;若该字符串已经存在,则覆盖
    1)头文件:stdlib.h
    2)int putenv(char *str);

  8. setenv
    1)头文件:stdlib.h
    2)int setenv(const char* name, const char* value, int rewrite);
    3)setenv将指定环境变量的值设置为参数指定值(更改环境变量字符串)
    4)若是name已经存在, rewrite不等于0,则删除其原先的定义;rewrite等于0,则不删除其原先的定义

  9. unsetenv
    1)头文件:stdlib.h
    2)int unsetenv(const char* name)

    1. 删除指定的环境变量字符串
发布了179 篇原创文章 · 获赞 1 · 访问量 7567

猜你喜欢

转载自blog.csdn.net/weixin_42596275/article/details/105480957