引入地址空间
静态变量和栈空间变量
静态变量默认是被初始化的
存放在初始化和为初始化空间中
static已经变成了全局变量
命令行参数和环境变量的增长方向
这里观察的是
命令行参数
和环境变量
的地址
观察命令行和环境变量表的地址
进程地址空间
如果他们是同一块儿空间,为什么打印的结果却不一样呢,我们知道肯定是父进程先跑完,在子进程进程输出的时候a应该是1才对——我们看到的只是
虚拟地址空间
1.
子进程是父进程的拷贝
,(父子进程代码和数据是共享的,只有在数据进行改变时才进行写时拷贝
,子进程继承父进程的pcb里的大部分内容,地址空间,页表,并且继承的时候每个页表对应的权限默认为只读的状态)他们通过页表进行映射到物理内存
,物理内存由操作系统进行管理
2.因为进程之间是独立的,他们本来对应的是相同的物理内存,但是当有一方进行改变
的时候,就需要将发生改变的那一方进行拷贝(写时拷贝
),更改页表的指向,指向新的物理空间
页表是有权限的
对数据的权限限制有r,w,rw,一般默认为r
字符串存在常量区,权限是只读的,操作系统检测到要修改变量,就会产生报错
加const是为了增强代码的安全性,错误早发现早处理
在父进程数据拷贝给子进程的时候,会将页表权限rw->r,因为子进程是父进程的拷贝,页表也会单独有一份,父进程和子进程的页表都会发生改变;当其中有一方进行修改数据,但是检测到页表对应的数据是只读的,此时os将介入,
重新开辟空间,将原来的数据拷贝过来,再进行修改
,完成后权限就会到了rw(缺页中断)
进程终止
进程退出状态:
1:代码执行完,结果正确
2:代码执行完,结果错误
3:代码没执行完,进程异常
只有代码执行完的退出结果才是有意义的
主函数退出——退出码
进程终止会有一个返回值(return)——表示退出情况,0表示成功,非0表示失败发生错误
使用echo $?
观察最后一次退出情况
第一次:139表示出错
第二三次:0表示正常退出
因为这个命令记录的是最后一次的退出情况,我们明白命令也是一种程序,echo是正常运行的,所以返回0
其他函数退出——错误码
调用库函数
,错误码错误码保存在errno
调用自己的函数
,普通函数的返回值一般表示的是函数的结果,特殊情况下,错误码需要自己设置
通过errno的方式观察库函数的错误码
进程异常
本质:收到
异常信号
每种信号都是一个宏,每个信号都是不一样的
exit & _exit
exit是库函数
_exit是系统调用
exit中的参数表示返回的退出码
_exit不会刷新缓冲区
exit会刷新缓冲区
证明缓冲区不是在系统中的
进程等待
wait
等待
任意一个进程
父进程等不到就卡死
我们能看到,父进程一直在等待,子进程一直在运行
waitpid
等待特定的pid
exit的参数是1可是为什么status返回的是256呢
status存的信息是错误码+信号
父进程和子进程
fork之后
谁先运行取决于调度器