提示文章写完后目录可以自动生成如何生成可参考右边的帮助文档文章目录一、初步进程的理解二、查看进程1、系统调用2、查看进程2.1查看进程命令3、初识父子进程3.1了解父进程3.2创建子进程一、初步进程的理解进程 PCB 代码段 数据段进程具有独立性1、父进程与子进程数据结构独立PCB独立2、代码共享代码只是只读3、数据以写时拷贝方式各自有一份1、编译一个可执行程序叫cmd(代码段和数据段)2、可执行程序二进制文件需要加载到内存把代码和数据加载到内存中内存中可以同时可以加载多个程序二进制文件操作系统也是二进制文件但是它第一个被加载到内存并拥有控制权管理者的程序普通程序是被管理者1.磁盘上所有命令都是二进制文件2.自己编译好的c编译好的代码也是二进制文件3.是二进制文件在运行之前磁盘上的文件4.根据冯诺依曼一个程序编译好就是一个二进制文件5.在linux系统中操作./cmd形成可执行程序二进制文件代码自己写的for和函数是代码数据代码自己定义的变量叫数据3、每加载一个可执行程序除了把程序加载到内存外操作系统内要对每一个被加载内存中的程序代码和数据对应在操作系统内核空间创建一个结构体PCB该结构体描述加载到内存程序属性等信息形成一个节点每个节点都有指针指向该程序和指向下一个节点的指针这个节点包含该程序所有属性和指针指向下一个节点操作系统必然要对多个被加载到内存中的程序进行管理1.操作系统内核中维护一个进程列表多个PCB可执行程序每个节点是一个进程控制块PCB用于描述一个程序的信息即程序的执行实例包括其代码、数据、堆栈、寄存器状态等。过PCB可以找到可执行程序有多少可执行程序对应有多少的PCB,多个PCB可执行程序形成进程列表未来在操作系统内部管理进程列表最后都会对进程列表的增删查改该列表是操作系统管理所有进程的核心数据结构。2.这个结构体PCB叫做进程控制块3.在linux下PCB叫 struct task_struct在linux系统中PCB叫task_ structtask_ struct包含以下内容• 提示符: 描述本进程的唯⼀标⽰符⽤来区别其他进程。• 状态: 任务状态退出代码退出信号等。• 优先级: 相对于其他进程的优先级。• 程序计数器: 程序中即将被执⾏的下⼀条指令的地址。• 内存指针:包括程序代码和进程相关数据的指针还有和其他进程共享的内存块的指针• 上下⽂数据:进程执⾏时处理器的寄存器中的数据[休学例⼦要加图CPU寄存器]。• I∕O状态信息:包括显⽰的I/O请求,分配给进程的I∕O设备和被进程使⽤的⽂件列表。• 记账信息:可能包括处理器时间总和使⽤的时钟数总和时间限制记账号等。• 其他信息二、查看进程在linux执行所有的指令、工具、自己的程序运行起来全部都是进程1、系统调用mangetpid用于获取当前进程的进程 PIDpid_t getpid(void)getpid是一个系统调用获得进程自己的PID在linux中PID是在task_struct里(因为他是2号手册2号手册是系统调用)拓展3号手册是库调用用于获取当前进程的父进程 PID(PPID)pid_t getppid(void)linux系统所有的进程是被它的父进程创建的子进程由父进程创建2、查看进程2.1查看进程命令1.查看系统进程的命令psaxj输出包含 PPID、PID、PGID、SID、TTY、CMD 等字段2.查看myprocess 的进程及其相关信息psaxj|grepmyprocess3.只显示 ps axj 输出的第一行也就是列标题行。psaxj|head-14.先显示进程列表的列标题再显示与特定进程相关的详细信息方便你对照理解筛选结果中每一列的含义psaxj|head-1;psaxj|grepmyprocesspsaxj|head-1psaxj|grepmyprocess解释1、可以查找到为myprocess的进程2、前一条命令成功head -1 总是成功后执行后面的命令。3、ps axj | grep myprocess再次列出所有进程并用 grep 筛选出包含 myprocess 字符串的行5.有PID就说明是一个进程./myprocess6.proc 记录当前系统所有进程的信息。而该目录下所有文件每一个数字目录代表的是特定进程的PID每个数字里的内容包含进程运行时动态属性一旦进程退出该目录被系统自动移除bash ls /proc列出 PID 为 21381 的进程目录下的内容(即查看该进程在 /proc 系统中所有运行时信息。ls/proc/21381-lexe每一个进程都有exe记录下进程对应可执行文件myprocesspcb会记录下来当前进程对应的可执行文件的绝对路径加程序名myprocess把绝对路径删掉程序还在跑因为删掉的时磁盘上的文件而进程启动时程序的拷贝已经在内存了cwdcwd(current worlk dir),是这个程序所在路径进程在启动时有PCB,PCB会记录当前所处的路径新建文件在当前路径下新建3、初识父子进程3.1了解父进程用于打印当前进程的 PID 和它的 父进程 PID#include stdio.h#include unistd.h // 声明 getpid() 和 getppid()intmain(){printf(我是一个进程!,我的pid: %d,我的父进程id: %d\n, getpid(), getppid());return0;}解释1.只能查找当前进程ID()和它的父进程的ID2.1每次创建一个进程每次重新运行 myprocess程序时操作系统都会创建一个全新的进程实例因此会分配一个全新的 PCB从而获得一个全新的 PID,所以该进程(myprocess进程实例的PID会变化2.2对于同一个进程实例myprocess进程实例即从创建到终止的这一次运行其 PID 不会中途改变2.3拓展PCB包含PIDpsajx|head-1psaxj|grep174395|grep-vgrep-bash是命令解释器-代表远程登陆os会给每一个登录用户分配一个bashmyprocess进程实例的父进程就是bash这是bash打印出来的字符服务器打开启动bash进程再打印字符串用户输入命令bash读取用户的命令调用系统接口执行这些命令并显示输出拓展ls,pwd,mkfdirtouch等这些命令的父进程都是bash3.2创建子进程1. 查看fork文挡manforkfork — 创建一个子进程fork - create a child process头文件#include unistd.hpid_t fork(void)解释;fork没有参数只有一个返回值pid_t 是一个有符号整数类型通常是 intfork() 的 return val返回值returnval解释1、成功时fork有两个返回值1.1 fork()返回值大于0 子进程的 PID一个正整数返回父进程1.2 fork() 返回值为 0返回子进程。2、失败时fork() 返回 -1并且不会创建子进程2. 代码验证#include stdio.h#include unistd.h#include sys/types.hintmain(){printf(父进程开始运行pid: %d\n, getpid());fork();printf(进程开始运行pid : %d\n,getpid());}结论fork() 一次调用确实会让一个进程变成两个进程父进程和子进程3. fork初步认识1、 进程 PCB 代码段 数据段2、父进程的 PCB 指向父进程的代码段和数据段3、子进程默认的PCB 指向父进程的代码段和数据段4、子进程的PCB是由父进程的PCB拷贝过来的复制完成后内核会对子进程 PCB 中的某些字段进行修改或重5、父进程只是创建子进程子进程目前没有自己的代码和数据因为目前没有执行程序代码段 数据段加载#include stdio.h#include unistd.hintmain(){fork();printf(Hello\n);return0;}fork() 调用后父进程创建子进程并且父进程和子进程是两个独立的进程。它们都会继续执行 fork() 之后的代码因此 printf(“Hello\n”) 被执行了两次一次在父进程中一次在子进程中。最终屏幕上会输出两行 Hello4. fork实操#include stdio.h#include unistd.h#include sys/types.hintmain(){printf(父进程开始运行,pid: %d\n, getpid());pid_tidfork();if(id0){perror(fork);return1;}elseif(id0){// child while(1){sleep(1);printf(我是一个子进程,我的pid: %d,我的父进程id: %d\n, getpid(), getppid());}}else{//father while(1){sleep(1);printf(我是一个父进程,我的pid: %d,我的父进程id: %d\n, getpid(), getppid());}}}解释没有执行fork()pid是1620,执行fork()我是一个父进程pid是1620父进程的父进程是bash19811我是一个子进程pid是1621父进程是1620所以fork()返回值大于0 时子进程的 PID一个正整数返回的是父进程结论1、通过 fork() 后子进程和父进程会分别进入 else if (id 0) 和 else 代码块并同时运行各自的 while(1) 循环2、这是因为 fork() 创建了一个新的子进程两个进程父与子从 fork()返回后同时运行问题1为什么fork() 返回后给父子进程返回各自的不同返回值答:在linux系统中一个父进程可以创建n(n0)子进程一个子进程只有一个父进程一定把子进程的PID返回父进程让父进程通过不同的PID来区分不同子进程父进程通过子进程的PID管理子进程总结所以系统设计的时候fork()返回值大于0 子进程的 PID一个正整数返回父进程 fork() 返回值为 0返回子进程。问题2为什么一个函数会返回两次答fork函数本质是一个系统调用fork是创建子进程的在fork内部在rerun返回后已经执行过父进程创建子进程有2个进程所以被返回2次问题3简单了解为什么一个变量 变量 0又大于0导致if和else同时成立答进程具有独立性父进程结束子进程不会结束代码是只读的是共享的数据默认是共享的如果父子进程一方进行修改数据OS把被修改的数据在底层拷贝一份让目标进程修改这个拷贝返回的本质是写入变量进程具有独立性1、父进程与子进程数据结构独立PCB独立2、代码共享代码只是只读3、数据以写时拷贝方式各自有一份写时拷贝如果子进程修改数据数据会拷贝一份让子进程访问拷贝数据父进程访问原有数据叫写时拷贝