首页
最新活动
服务器租用
香港服务器租用
台湾服务器租用
美国服务器租用
日本服务器租用
新加坡服务器租用
高防服务器
香港高防服务器
台湾高防服务器
美国高防服务器
裸金属
香港裸金属服务器
台湾裸金属服务器
美国裸金属服务器
日本裸金属服务器
新加坡裸金属服务器
云服务器
香港云服务器
台湾云服务器
美国云服务器
日本云服务器
CDN
CDN节点
CDN带宽
CDN防御
CDN定制
行业新闻
官方公告
香港服务器资讯
帮助文档
wp博客
zb博客
服务器资讯
联系我们
关于我们
机房介绍
机房托管
登入
注册
帮助文档
专业提供香港服务器、香港云服务器、香港高防服务器租用、香港云主机、台湾服务器、美国服务器、美国云服务器vps租用、韩国高防服务器租用、新加坡服务器、日本服务器租用 一站式全球网络解决方案提供商!专业运营维护IDC数据中心,提供高质量的服务器托管,服务器机房租用,服务器机柜租用,IDC机房机柜租用等服务,稳定、安全、高性能的云端计算服务,实时满足您的多样性业务需求。 香港大带宽稳定可靠,高级工程师提供基于服务器硬件、操作系统、网络、应用环境、安全的免费技术支持。
联系客服
服务器资讯
/
香港服务器租用
/
香港VPS租用
/
香港云服务器
/
美国服务器租用
/
台湾服务器租用
/
日本服务器租用
/
官方公告
/
帮助文档
【linux】进程-查看进程-PID值-fork原理
发布时间:2024-02-27 20:48:47 分类:帮助文档
【linux】进程|查看进程|PID值|fork原理 文章目录 1. 什么是进程管理本质的解释描述组织 结论 2.查看进程查看进程方法1创建终端输入命令显示进程一个程序存在多个进程 查看进程方法2查看成功查看失败结论 3.通过系统调用获取进程标识符1.获取PID值验证PID值是否正确 2. 获取父进程PID值验证3. 父进程为什么不变化?4. 为什么都是bash? 4.指定进程暂停5.如何创建子进程1. fork返回值2.使父子进程执行不同的任务3. 结论 6. fork 原理1.fork做了什么2.fork 如何看待代码和数据父子进程指向同一块代码和数据,独立性如何保证? 3.fork如何理解两个返回值问题 1. 什么是进程 假设在一个文件中写代码,并生成一个可执行程序在磁盘中,可执行程序本质也是一个二进制文件 文件 =内容+属性 内容即 自己写的代码和数据 属性即 创建时间、权限等信息 使用 ./ 将其加载到内存中,cpu访问代码和数据,从而执行代码, 把代码和数据放入内存中 就可以叫做进程么?当然不是! - 举例: 如何成为你的学校的学生呢? 只要想办法进入你的学校里,在学校里,就是你的学校的学生么? 当然不是,看门的大爷和楼管阿姨也在学校里 想要成为学生,必须在学籍档案中有你个人的基本信息 同理,只把代码和数据放入内存中,不叫作进程 为什么基本信息在学籍档案中呢? 因为学校要对学生管理 随着程序加载到内存的数量增多,操作系统就要考虑如何把加载的代码个数据进行管理, 所以操作系统要管理进程 管理的本质是先描述,在管理 (不懂的可以点击查看具体解释) 管理本质的解释 描述 使用结构体构建了结构体对象,在操作系统教材中叫做 PCB ,在Linux中叫做 task_struct 并且结构体提取了所有进程的属性 同样使用各自的结构体,可以找到各自的代码和数据 组织 将结构体通过特定数据结构关联起来(以链表为例) 通过链表的增删查改操作,来完成对进程的增加、删除、查找、修改 结论 进程是内核关于进程的相关数据结构+当前进程的代码和数据 2.查看进程 查看进程方法1 #include
2 #include
3 int main() 4 { 5 while(1) 6 { 7 printf("hello world\n"); 8 sleep(1); 9 } 10 return 0; 11 } 创建一个pro.c的文件,同时生成一个可执行程序pro,使之无线循环下去 创建终端 在第一个终端中点击右键,复制SSH渠道,就会自动生成终端2 输入命令显示进程 在保证终端1的pro程序运行时,在第二个终端中 ps axj 查看当前系统中所有的进程 head -1 取第一行指令 grep pro 只查看自己的进程 grep -v grep 除了grep的内容显示出来 输入 ps axj | head -1 && ps axj | grep pro | grep -v grep,即可查看当前pro可执行程序的进程 [yzq@VM-8-8-centos ~]$ ps axj | head -1 && ps axj | grep pro | grep -v grep PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 3754 3943 3943 3754 pts/0 3943 S+ 1002 0:00 ./pro 一个程序存在多个进程 首先创建三个终端 在终端2和终端3中同时运行 ./pro ,再次在终端1中使用指令ps axj | head -1 && ps axj | grep pro | grep -v grep,发现生成两个PID值不同的进程将一个可执行程序多次加载内存,可执行程序内部存在多个进程 查看进程方法2 ls /proc,proc 为process的简称,保存进程相关属性的目录 蓝色的数字就是进程的PID 查看成功 在保证终端1正在运行./pro,在终端2中以第一次生成的PID为例 PID值为3943,ls proc/3943,即可查看相关的进程属性 查看失败 若将终端1的pro可执行程序关闭,则进程不存在 [yzq@VM-8-8-centos ~]$ ls /proc/28439 ls: cannot access /proc/28439: No such file or directory 结论 当把进程创建时,proc目录下会自动创建以PID命名的目录,里面会把内存运行的属性呈现出来 当把进程终止时,proc目录下会自动把PID命名的目录全部删除 3.通过系统调用获取进程标识符 1.获取PID值 getpid 需要头文件
和
,返回值为 getpid_t类型,表示当前进程的PID值 #include
2 #include
3 #include
4 int main() 5 { 6 while(1) 7 { 8 printf("我已经是一个进程了,PID为:%d\n",getpid()); 9 sleep(1); 10 } 11 return 0; 12 } 在之前的pro.c文件进行修改,将其内容修改为上面的,并在终端1中使用./pro 执行可执行程序 [yzq@VM-8-8-centos lesson]$ ./pro 我已经是一个进程了,PID为:28286 我已经是一个进程了,PID为:28286 我已经是一个进程了,PID为:28286 我已经是一个进程了,PID为:28286 我已经是一个进程了,PID为:28286 我已经是一个进程了,PID为:28286 我已经是一个进程了,PID为:28286 会生成不间断的相同PID值 验证PID值是否正确 再次创建一个终端,并命名为终端2,并保证上述的pro程序在终端1中运行的情况下,使用指令 ps axj | head -1 && ps axj | grep pro | grep -v grep,发现PID值相同 [yzq@VM-8-8-centos lesson]$ ps axj | head -1 && ps axj | grep pro | grep -v grep PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 26652 28286 28286 26652 pts/0 28286 S+ 1002 0:00 ./pro 2. 获取父进程PID值 getppid 头文件与getpid相同,返回值为父进程的PID值 1 #include
2 #include
3 #include
4 int main() 5 { 6 while(1) 7 { 8 printf("我已经是一个进程了,PID为:%d,我的父进程PID为:%d\n",getpid(),getppid()); 9 sleep(1); 10 } 11 return 0; 12 } 再次将终端1中的pro.c文件内容修改为上面 [yzq@VM-8-8-centos lesson]$ ./pro 我已经是一个进程了,PID为:1013,我的父进程PID为:32452 我已经是一个进程了,PID为:1013,我的父进程PID为:32452 我已经是一个进程了,PID为:1013,我的父进程PID为:32452 我已经是一个进程了,PID为:1013,我的父进程PID为:32452 在终端1中输入./pro,显示当前进程PID为 1013,父进程PID为 32452 验证 ,在确保终端1中的pro可执行程序正在运行,打开终端2, 输入ps axj | head -1 && ps axj | grep pro | grep -v grep 指令 [yzq@VM-8-8-centos lesson]$ ps axj | head -1 && ps axj | grep pro | grep -v grep PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 32452 1013 1013 32452 pts/2 1013 S+ 1002 0:00 ./pro 说明使用getppid查询结果正确 3. 父进程为什么不变化? [yzq@VM-8-8-centos lesson]$ ./pro 我已经是一个进程了,PID为:2050,我的父进程PID为:32452 ^C [yzq@VM-8-8-centos lesson]$ ./pro 我已经是一个进程了,PID为:2059,我的父进程PID为:32452 ^C [yzq@VM-8-8-centos lesson]$ ./pro 我已经是一个进程了,PID为:2065,我的父进程PID为:32452 ^C 在终端1中多次运行./pro,发现当前进程PID一直在变,而父进程的PID没变过父进程的PID为32452,在终端2中输入, ps ajx | head -1 && ps ajx |grep 32452 指令 [yzq@VM-8-8-centos lesson]$ ps ajx | head -1 && ps ajx |grep 32452 PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 907 3167 3166 907 pts/3 3166 R+ 1002 0:00 grep --color=auto 32452 32451 32452 32452 32452 pts/2 32452 Ss+ 1002 0:00 -bash 说明父进程PID 为 -bash bash为命令行解释器,本质上也是一个进程 命令行启动的所有程序,最终都会变成进程,而该进程对应的父进程都是bash 4. 为什么都是bash? bash怕你写的代码有问题,所以使用bash创建的子进程完成任务,这样就算是挂了,bash也没事 4.指定进程暂停 在终端1中运行./pro,在终端2中输入 kill - 9+自己进程的PID [yzq@VM-8-8-centos lesson]$ ./pro 我已经是一个进程了,PID为:29031,我的父进程PID为:28428 我已经是一个进程了,PID为:29031,我的父进程PID为:28428 我已经是一个进程了,PID为:29031,我的父进程PID为:28428 我已经是一个进程了,PID为:29031,我的父进程PID为:28428 我已经是一个进程了,PID为:29031,我的父进程PID为:28428 我已经是一个进程了,PID为:29031,我的父进程PID为:28428 我已经是一个进程了,PID为:29031,我的父进程PID为:28428 我已经是一个进程了,PID为:29031,我的父进程PID为:28428 我已经是一个进程了,PID为:29031,我的父进程PID为:28428 我已经是一个进程了,PID为:29031,我的父进程PID为:28428 我已经是一个进程了,PID为:29031,我的父进程PID为:28428 我已经是一个进程了,PID为:29031,我的父进程PID为:28428 我已经是一个进程了,PID为:29031,我的父进程PID为:28428 我已经是一个进程了,PID为:29031,我的父进程PID为:28428 Killed 在终端2中输入 kill - 9 29031,即可在终端1中显示killed,表示结束 5.如何创建子进程 创建子进程—— fork,头文件为
,返回值是 pid_t类型 #include
2 #include
3 #include
4 int main() 5 { 6 printf("AAAA\n"); 7 fork(); 8 printf("BBBB\n"); 9 sleep(1); 10 return 0; 11 } 继续在终端1中修改pro.c文件中的内容如上 [yzq@VM-8-8-centos lesson]$ ./pro AAAA BBBB BBBB 运行pro可执行程序,发现竟然执行两次BBBB 这是为什么呢?我们继续往下看 #include
2 #include
3 #include
4 int main() 5 { 6 printf("AAAA\n"); 7 fork(); 8 printf("BBBB:pid:%d,ppid:%d\n",getpid(),getppid()); 9 sleep(1); 10 return 0; 11 } 修改por.c文件的内容,加上自己和父进程的PID值 [yzq@VM-8-8-centos lesson]$ ./pro AAAA BBBB:pid:4285,ppid:31919 BBBB:pid:4286,ppid:4285 终端1中./pro运行可执行程序,两个执行B的printf语句打印自己进程的PID值不同,说明是两个进程而下面BBBB的父进程PID与上面BBBB的子进程PID相同,说明创建了子进程 1. fork返回值 父进程返回子进程的PID值,子进程返回0,失败返回-1 1 #include
2 #include
3 #include
4 int main() 5 { 6 printf("AAAA\n"); 7 pid_t ret= fork(); 8 printf("BBBB:pid:%d,ppid:%d,%d,%p\n",getpid(),getppid(),ret,&ret); 9 sleep(1); 10 return 0; 11 } 修改pro.c文件内容,加上ret的值和地址 [yzq@VM-8-8-centos lesson]$ ./pro AAAA BBBB:pid:7799,ppid:31919,7800,0x7ffefc72c02c BBBB:pid:7800,ppid:7799,0,0x7ffefc72c02c 在终端1中运行./pro,上面的BBBB,ret值返回是下面BBBB的PID值 ,说明是父进程 而下面的BBBB,ret值为0,说明是子进程 2.使父子进程执行不同的任务 #include
2 #include
3 #include
4 int main() 5 { 6 pid_t ret= fork(); 7 if(ret==0) 8 { 9 //子进程 10 while(1) 11 { 12 printf("我是子进程,我的pid是:%d,我的父进程是:%d\n",getpid(),getppid()); 13 sleep(1); 14 } 15 16 } 17 else if(ret>0) 18 { 19 //父进程 20 while(1) 21 { 22 printf("我是父进程,我的pid是:%d,我的父进程是:%d\n",getpid(),getppid()); 23 sleep(1); 24 } 25 } 26 else 27 { //报错 29 } 30 return 0; } 修改pro.c文件的内容,设置if else语句实现 [yzq@VM-8-8-centos lesson]$ ./pro 我是父进程,我的pid是:13505,我的父进程是:31919 我是子进程,我的pid是:13506,我的父进程是:13505 我是子进程,我的pid是:13506,我的父进程是:13505 我是父进程,我的pid是:13505,我的父进程是:31919 我是子进程,我的pid是:13506,我的父进程是:13505 我是父进程,我的pid是:13505,我的父进程是:31919 我是父进程,我的pid是:13505,我的父进程是:31919 我是子进程,我的pid是:13506,我的父进程是:13505 父进程和子进程是同时运行的 说明在多执行流的环境下 if和else if可以同时成立 3. 结论 fork之后,执行流会变成2个fork之后,谁先运行由调度器决定fork之后,fork之后的代码共享,通常通过if和else if来进行执行流分流 6. fork 原理 1.fork做了什么 子进程pcb的大部分属性会以父进程pcb为模板,把父进程大部分里面的数据拷给子进程 小部分属于子进程私有的,例如PID、PPID值 因为进程等于数据结构+代码和数据,所以父进程指向自己的代码和数据,子进程也会指向同样的代码和数据 创建子进程:创建独立的pcb结构,父子进程看到的是同一份代码和数据 2.fork 如何看待代码和数据 当我们把画图关闭后,并不会影响有道云笔记的使用,说明他们都是独立存在的 进程在运行的时候,是具有独立性的 当我们在执行代码同时运行父子进程时,若使用 kill- 9 干掉父进程后,子进程仍能运行 父子进程在运行时,也是具有独立性的 父子进程指向同一块代码和数据,独立性如何保证? 代码: 代码在内存区域是只读的(从来不会自己发生变化,不会有人修改) 父子进程两者都读,不会互相影响 数据: 1 #include
2 #include
3 #include
4 int main() 5 { 6 int x=100; 7 pid_t ret= fork(); 8 if(ret==0) 9 { 10 //子进程 11 while(1) 12 { 13 printf("我是子进程,我的pid是:%d,我的父进程是:%d,%d\n",getpid(),getppid(),x); 14 sleep(1); 15 } 16 17 } 18 else if(ret>0) 19 { 20 //父进程 21 while(1) 22 { 23 printf("我是父进程,我的pid是:%d,我的父进程是:%d,%d\n",getpid(),getppid(),x); 24 x=50; 25 sleep(1); 26 } 27 } 28 return 0; 29 } 在终端1中修改pro.c文件的内容 [yzq@VM-8-8-centos lesson]$ ./pro 我是父进程,我的pid是:26332,我的父进程是:21231,100 我是子进程,我的pid是:26333,我的父进程是:26332,100 我是父进程,我的pid是:26332,我的父进程是:21231,50 我是子进程,我的pid是:26333,我的父进程是:26332,100 我是父进程,我的pid是:26332,我的父进程是:21231,50 我是子进程,我的pid是:26333,我的父进程是:26332,100 我是父进程,我的pid是:26332,我的父进程是:21231,50 我是子进程,我的pid是:26333,我的父进程是:26332,100 使用./pro执行可执行程序,修改父进程中的x值后,只有父进程的x值被修改,子进程x值不变 说明如果有一个进程把数据改了,并不会影响另一个进程 当有一个执行流尝试修改数据的时候,操作系统自动给当前进程触发:写时拷贝4 3.fork如何理解两个返回值问题 当我们函数内部准备执行return的时候,我们的主体功能已经完成fork本质上是操作系统提供的一个创建子进程的函数所以当到return时,说明创建子进程已经完成了,return语句,父进程会执行一次,子进程执行一次,共执行两次
上一篇
内网搭建 SFTP 服务器
下一篇
服务器托管租用费用怎么算
相关文章
vps怎么与本机复制粘贴
iPad Pro如何使用SSH远程连接服务器云端编程开发【内网穿透】
新年迎新丁!PowerEdge服务器家族迎来新成员
腾讯云服务器购买真便宜,高配服务器超低价_附优惠购买链接
Load balancer does not have available server for client- userservice
服务器内存条怎么区分
二级域名怎么绑定到空间
CentOS系统中设置反向代理服务器的步骤
备案网站无法进入怎么办
香港云服务器租用推荐
服务器租用资讯
·广东云服务有限公司怎么样
·广东云服务器怎么样
·广东锐讯网络有限公司怎么样
·广东佛山的蜗牛怎么那么大
·广东单位电话主机号怎么填写
·管家婆 花生壳怎么用
·官网域名过期要怎么办
·官网邮箱一般怎么命名
·官网网站被篡改怎么办
服务器租用推荐
·美国服务器租用
·台湾服务器租用
·香港云服务器租用
·香港裸金属服务器
·香港高防服务器租用
·香港服务器租用特价
7*24H在线售后
高可用资源,安全稳定
1v1专属客服对接
无忧退款试用保障
德讯电讯股份有限公司
电话:00886-982-263-666
台湾总部:台北市中山区建国北路一段29号3楼
香港分公司:九龙弥敦道625号雅兰商业二期906室
服务器租用
香港服务器
日本服务器
台湾服务器
美国服务器
高防服务器购买
香港高防服务器出租
台湾高防服务器租赁
美国高防服务器DDos
云服务器
香港云服务器
台湾云服务器
美国云服务器
日本云服务器
行业新闻
香港服务器租用
服务器资讯
香港云服务器
台湾服务器租用
zblog博客
香港VPS
关于我们
机房介绍
联系我们
Copyright © 1997-2024 www.hkstack.com All rights reserved.