文章目录 1. 什么是进程管理本质的解释描述组织 结论 2.查看进程查看进程方法1创建终端输入命令显示进程一个程序存在多个进程 查看进程方法2查看成功查看失败结论
假设在一个文件中写代码,并生成一个可执行程序在磁盘中,可执行程序本质也是一个二进制文件
文件 =内容+属性
内容即 自己写的代码和数据
属性即 创建时间、权限等信息
随着程序加载到内存的数量增多,操作系统就要考虑如何把加载的代码个数据进行管理,
所以操作系统要管理进程
管理的本质是先描述,在管理 (不懂的可以点击查看具体解释)
使用结构体构建了结构体对象,在操作系统教材中叫做 PCB ,在linux中叫做 task_struct
并且结构体提取了所有进程的属性
同样使用各自的结构体,可以找到各自的代码和数据
将结构体通过特定数据结构关联起来(以链表为例)
通过链表的增删查改操作,来完成对进程的增加、删除、查找、修改
进程是内核关于进程的相关数据结构+当前进程的代码和数据
#include 2 #include<unistd.h> 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
首先创建三个终端
ps axj | head -1 && ps axj | grep pro | grep -v grep
,发现生成两个PID值不同的进程ls /proc
,proc 为process的简称,保存进程相关属性的目录
ls proc/3943
,即可查看相关的进程属性[yzq@VM-8-8-centos ~]$ ls /proc/28439ls: cannot access /proc/28439: No such file or directory
当把进程创建时,proc目录下会自动创建以PID命名的目录,里面会把内存运行的属性呈现出来
当把进程终止时,proc目录下会自动把PID命名的目录全部删除
getpid
需要头文件 #include 2 #include<sys/types.h> 3 #include<unistd.h> 4 int main() 5 { 6 while(1) 7 { 8 printf("我已经是一个进程了,PID为:%d\n",getpid());9 sleep(1); 10 } 11 return 0; 12 }
[yzq@VM-8-8-centos lesson]$ ./pro我已经是一个进程了,PID为:28286我已经是一个进程了,PID为:28286我已经是一个进程了,PID为:28286我已经是一个进程了,PID为:28286我已经是一个进程了,PID为:28286我已经是一个进程了,PID为:28286我已经是一个进程了,PID为:28286
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 COMMAND26652 28286 28286 26652 pts/0 28286 S+ 1002 0:00 ./pro
getppid
头文件与getpid
相同,返回值为父进程的PID值
1 #include<stdio.h> 2 #include<sys/types.h> 3 #include<unistd.h> 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 }
[yzq@VM-8-8-centos lesson]$ ./pro我已经是一个进程了,PID为:1013,我的父进程PID为:32452我已经是一个进程了,PID为:1013,我的父进程PID为:32452我已经是一个进程了,PID为:1013,我的父进程PID为:32452我已经是一个进程了,PID为:1013,我的父进程PID为:32452
./pro
,显示当前进程PID为 1013,父进程PID为 32452ps 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 COMMAND32452 1013 1013 32452 pts/2 1013 S+ 1002 0:00 ./pro
getppid
查询结果正确[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
./pro
,发现当前进程PID一直在变,而父进程的PID没变过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 3245232451 32452 32452 32452 pts/2 32452 Ss+ 1002 0:00 -bash
说明父进程PID 为 -bash
bash为命令行解释器,本质上也是一个进程
命令行启动的所有程序,最终都会变成进程,而该进程对应的父进程都是bash
bash怕你写的代码有问题,所以使用bash创建的子进程完成任务,这样就算是挂了,bash也没事
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为:28428Killed
kill - 9 29031
,即可在终端1中显示killed
,表示结束创建子进程—— fork
,头文件为
#include 2 #include<sys/types.h> 3 #include<unistd.h> 4 int main() 5 { 6 printf("AAAA\n"); 7 fork(); 8 printf("BBBB\n"); 9 sleep(1); 10 return 0; 11 }
[yzq@VM-8-8-centos lesson]$ ./proAAAABBBBBBBB
#include 2 #include<sys/types.h> 3 #include<unistd.h> 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 }
[yzq@VM-8-8-centos lesson]$ ./proAAAABBBB:pid:4285,ppid:31919BBBB:pid:4286,ppid:4285
./pro
运行可执行程序,两个执行B的printf语句打印自己进程的PID值不同,说明是两个进程 1 #include<stdio.h> 2 #include<sys/types.h> 3 #include<unistd.h> 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 }
[yzq@VM-8-8-centos lesson]$ ./proAAAABBBB:pid:7799,ppid:31919,7800,0x7ffefc72c02cBBBB:pid:7800,ppid:7799,0,0x7ffefc72c02c
在终端1中运行./pro
,上面的BBBB,ret值返回是下面BBBB的PID值 ,说明是父进程
而下面的BBBB,ret值为0,说明是子进程
#include 2 #include<sys/types.h> 3 #include<unistd.h> 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; }
[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可以同时成立
子进程pcb的大部分属性会以父进程pcb为模板,把父进程大部分里面的数据拷给子进程
小部分属于子进程私有的,例如PID、PPID值
因为进程等于数据结构+代码和数据,所以父进程指向自己的代码和数据,子进程也会指向同样的代码和数据
创建子进程:创建独立的pcb结构,父子进程看到的是同一份代码和数据
当我们把画图关闭后,并不会影响有道云笔记的使用,说明他们都是独立存在的
进程在运行的时候,是具有独立性的
当我们在执行代码同时运行父子进程时,若使用 kill- 9 干掉父进程后,子进程仍能运行
父子进程在运行时,也是具有独立性的
代码:
代码在内存区域是只读的(从来不会自己发生变化,不会有人修改)
父子进程两者都读,不会互相影响
数据:
1 #include<stdio.h> 2 #include<sys/types.h> 3 #include<unistd.h> 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 }
[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
来源地址:https://blog.csdn.net/qq_62939852/article/details/128723839
--结束END--
本文标题: 【linux】进程|查看进程|PID值|fork原理
本文链接: https://www.lsjlt.com/news/418468.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0