目录
- 一、前言
- 二、进程查询
- 三、进程创建
- 1.创建操作
- 2.返回值疑云
一、前言
本篇文章的探讨是基于一定的进程理解的,在此基础上对有关进程的操作进行讲解。
二、进程查询
首先我们来认识一下进程查询的指令
ps ajx |head -1&& ps ajx |grep process |grep -v grep
//其中process可以替换为其他的可执行程序
查询的结果就会像图片里一样,有pid和ppid等信息。
其中,pid是每个进程所特有的,每个进程的pid都会不同,甚至每一个可执行程序的每一次执行,都会产生不同的pid,但是他们的ppid都是相同的。
除了这种通过指令可以显示进程信息之外,我们还可以通过在程序内调用函数的方法进行显示。
三、进程创建
1.创建操作
进程创建我们一般使用fork函数,我们先来直接使用一下。
int main()
5 {
6 printf("this is pid %d,this is ppid %d\n",getpid(),getppid());
7 fork();
8 printf("this is pid %d,this is ppid %d\n",getpid(),getppid());
9 return 0;
10 }
执行之后,我们会发现一个现象,在fork之后的printf语句被执行了两遍,并且是执行了一遍父进程和一遍子进程。
这里是因为在fork之后,本身是有一个父子的代码共享。所以在父子进程中都对这个printf语句进行了执行,并且是以各自的身份,所以就出现了不同的pid。
但是一般情况下,我们肯定都是想让父子执行不同的代码,所以我们就要对fork的返回值进行进一步研究。
fork的返回值是返回两次,两个数字,如果返回的是小于0的数字,那么就是创建失败,如果创建成功,则返回的==0的分支就是子进程,返回的大于0的分支就是父进程,其实就是子进程的pid。
下面举个例子分析一下。
int main()
5 {
6 printf("this is pid %d,this is ppid %d\n",getpid(),getppid());
7 int d=fork();
8 if (d<0)
9 {
10 return -1;
11 }
12 else if(d==0)
13 {
14 while(1)
15 {
16 printf("我是子进程:this is pid %d,this is ppid %d\n",getpid(),getppid());
17 sleep(1);
18 }
19 }
20 else
21 {
22 while(1)
23 {
24 printf("我是父进程:this is pid %d,this is ppid %d\n",getpid(),getppid());
25 sleep(1);
26 }
27 }
28 return 0;
29 }
这就是输出结果,我们分别让这两个进程运行。
2.返回值疑云
1.为什么针对父进程和子进程的返回值会有不同?
首先是要通过两种进程的返回值差距来在后续if-else中分流运行。那为什么父进程要子进程的pid呢,因为这样是为了方便父进程记录子进程的pid,后续在进程回收等等阶段使用。
2.为什么fork要返回两次,为什么可以返回两次?
fork返回两次就是为了返回两个不同的值,然后后续进行分流运行。至于为什么可以返回两次,我们可以将return看做是一次返回写入,所以两次return其实也就是两次写入,而fork在结束之前就已经创建出了子进程,所以通过两个进程就可以返回两个return。
3.同一个返回值变量,为什么可以承载不同的变量值?
这里是牵扯到一个父子进程数据分配的问题,在产生子进程的时候,父进程的大部分数据都会传递给子进程,和代码一样,共享一块区域,这个返回值就是两者共同拥有的,但是因为fork的返回值不同,所以数据上就发生了改变,在发生了改变之后,我们就得有个写时拷贝,将两个变量地址给分开,这时候不同进程就可以拥有不同值的同一个变量了。
创作不易,感谢阅读。