目录
进程
程序
就是一个指令序列;早期的计算机只支持单道程序。程序的代码放在程序段中,程序运行过程处理的数据放在数据段内(如变量)
程序段存放在内存的低地址,数据段存放在内存的高地址位置。CPU执行指令时,到内存的低地址取得指令,按照指令执行,当寻找变量时,到内存的高地址取得数据
引入多道程序技术之后:
为了方便操作系统管理,完成各种程序并发执行,引入了进程、进程实体的概念
操作系统为每个运行的程序配置了一个数据结构(结构体),成为进程控制块PCB, 用来描述进程的各种信息
PCB、程序段、数据段三部分组成了进程实体 ==> 简称进程
PCB是进程存在的唯一标志
进程
1.进程是程序的一次执行过程
2.进程是一个程序及其数据在处理机上顺序执行时发生的活动
3.进程是具有独立功能的程序在数据集合上运行的过程。他是系统进行资源分配和调度的一个独立单位
进程是一个动态的过程
进程是进程实体的运行过程 进程实体是静态的,进程则是动态的
可以理解为程序和进程,前者是舞台剧的剧本;后者是舞台剧,是戏剧,是动态的
孤儿进程
父进程先于子进程终止,子进程沦为“孤儿进程”,会被 init 进程领养。
僵尸进程
子进程终止。父进程尚未对子进程进行回收,在此期间子进程沦为“僵尸进程”。
并发
在操作系统中,一个时间段内有多个进程都处于已启动运行到运行完毕之间的状态,但一个时间点上仍只有一个进程在运行
进程控制块PCB
进程id、进程的状态(就绪态、运行态、挂起态、终止态)
进程切换时需要保存和恢复的一些CPU寄存器
描述虚拟地址空间的信息
当前工作目录
umask掩码、文件描述符表、和信号相关的信息
用户 id 和组 id
CPU和MMU
MMU:分页内存管理单元
MMU位于处理器内核和连接高速缓存以及物理存储器的总线之间。当处理器内核取指令或者存储数据的时候,都会提供一个有效地址,或称之为逻辑地址、虚拟地址
每条MMU匹配规则所对应的存储的的大小定义为页。页的大小通常设定为不会对程序的性能造成显著影响的最小的程序和代码的长度(通常为4K).当暂时不使用物理内存的内容时,可将其保存到硬盘等外部存储器里,将其空间用于其他程序,当再次使用这部分内容时再从外部存储器写回到实际物理内存中。通过这种方法,系统就可以提供多于实际物理内存容量的虚拟内存
主要作用:虚拟内存与物理内存之间的映射、设置修改内存访问级别
进程相关函数
fork
函数原型:pid_t fork(void) //创建子进程。父进程各自返回。
//父进程返回子进程pid。子进程返回0
getpid():获取进程id
getppid():获取父进程id //用于循环创建N个子进程、每个子进程表明自己身份
wait/waitpid
wait函数:pid_t wait(int *status) 回收子进程退出资源
参数:(传出)回收进程的状态
返回值: 成功:回收进程的pid
失败:-1,errno
函数作用:
阻塞等待子进程退出
清理子进程残留在内核的pcb资源
通过传出参数,得到子进程结束状态
获取子进程正常终止值 WFIEXITED(status)
获取导致子进程异常终止信号 WIFSIGNALED(status)
waitpid函数:pid_t waitpid(pid_t pid, int *status, int optains) 指定某一个进程进行回收
参数:
pid:指定回收的子进程pid
>0:待回收的子进程pid
0: 同组的子进程
-1: 任意的子进程
status:(传出)回收进程的状态
options:WNOHANG,指定回收方式为非阻塞方式
返回值:
>0:表成功回收的子进程pid
0: 函数调用时,制定了非阻塞方式,没有子进程结束
-1:失败, errno
wait/waitpid 只能回收子进程。一次调用回收一个。可以通过while实现循环回收
/*
代码功能: 循环创建5个子进程并打印出各自的进程id
回收第三个创建出来的子进程
创建时间: 20点55分
作者: 哈哈.txt
*/
int main(int argc, char *argv[])
{
pid_t pid, wpid, tmpid;
int i;
for(i = 0; i < 5; i++) {
pid = fork();
if(pid == 0)
break;
if(i == 2) {
tmpid = pid;
printf("=====pid = %d\n", pid);
}
}
if(5 == i) {
sleep(5);
printf("--in parent, befor waitpid pid = %d\n", tmpid);
wpid = waitpid(tmpid, NULL, WNOHANG);
printf("i am parent, wait a child finish:%d\n", wpid);
}else {
sleep(i);
printf("i am %th, pid = %d\n", i+1, getpid());
}
return 0;
}
进程共享
父子进程相同
刚 fork 后。data段、text段、堆、栈、变量环境、全局变量、宿主目录位置、进程工作目录位置、信号处理方式
父子进程不同
进程id、返回值、各自的父进程、进程创建时间、闹钟、未决信号集
父子进程共享
读时共享、写时复制 ==== 全局变量
gdb调试
设置父进程调试路径:set follow-fork-mode parent
设置子进程调试路径:set follow-fork-mode child