Linux中getpid、getppid与fork,创建子进程的过程和问题.

发布于:2022-12-06 ⋅ 阅读:(272) ⋅ 点赞:(0)

🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸
在这里插入图片描述

getpid、getppid与fork

1.getpid准备

这两个命令需要手动安装

sudo yum install -y man-pages

从man手册中可以看出,需要包含头文件

#icnlude <sys/types.h>

在这里插入图片描述
执行的代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
	while(1)
	{
		pid_t id = getpid();//需要包含头文件#include<sys/types.h>
		//pid_t是操作系统提供的数据类型,实际上就是无符号整型
		printf("hello zhupi  pid:%d\n",id);
		sleep(1);//需要包含头文件#include <unistd.h>
	}
	return 0;
}

<sys/types.h>和<unistd.h>这两个头文件并不是C语言提供的,而是操作系统提供的。

2.getpid应用

getpid是取到进程的pid,那么只有在变成了进程之后,函数才会被调用
在这里插入图片描述
在这里插入图片描述

3. 结束进程

1.在运行所在的终端Ctrl C进行终止(相当于在任务管理器去结束任务)
2.通过其他终端的命令

kill -9 进程PID
//给具有该PID的进程发送9号信号 进行结束进程

4.getppid准备

parent process 父进程ID
在这里插入图片描述
执行的代码:

  #include <stdio.h>
  #include <unistd.h>
  #include <sys/types.h>
  int main()
  {
    while(1)
    {
      pid_t id=getpid();
      pid_t pid=getppid();
      printf("hello zhupi. pid:%d.ppid:%d\n",id,pid);
      sleep(1);
    }
    return 0;
 } 

5.getppid应用

在这里插入图片描述
在这里插入图片描述

6.bash与操作系统

可以看出,它的父进程是bash,一个shell外壳程序
不管是执行自己的代码,还是系统命令,它的父进程永远是bash
也就是说自己启动程序是bash通过创建子进程的方式来让我们完成的
永远都是以bash的子进程的方式在运行

kill掉bash,就不能正常工作了,每一个终端都有一个bash,每个终端的bash都是不同的,每一次登录的时候,就是创建bash的时候,有bash才能正常运行,输入密码成功了,系统就会指派一个bash来做父进程创建子进程,bash的父进程就是操作系统了

操作系统只要我不关机,他就一直运行,所以可以看出,操作系统是一个死循环

7. 通过代码创建子进程 fork

在这里插入图片描述
从man手册可以看出fork需要包含头文件 unistd.h

pid_t fork();

1.失败的时候,返回-1
2.成功的时候,有两个返回值
a.子进程的PID返回给父进程
b.子进程返回0

在这里插入图片描述
执行的代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/typid.h>
int main()
{
	printf("I am parent proccess! pid:%d\n",getpid());
	pid_t ret =fork();
	fork();
	printf("ret:%d,pid:%d,ppid:%d\n",ret,getpid(),getppid());
	sleep(1);
	return 0;
}

在这里插入图片描述
父进程的PPID是bash
子进程的PPID是父进程

同时,子进程创建出来,并不是为了让子进程和父进程做一样的事的,虽然下面的代码共享,但是我可以条件语句让你选择执行,让其父子进程在之后执行不同的代码,能这样的原因就是因为fork之后有两个不同的执行流

在这里插入图片描述

在云服务器当中有复制会话和赋值SSH渠道
复制会话是重新建立一个新的线程
复制SSH渠道是共同同一个线程

while : ; do ps axj | head -1 && ps axj | grep "fork_test" | grep -v "grep" ; sleep 1 ; done ;

表示循环打印fork_test进程并且不匹配关于grep的进程
在这里插入图片描述

8.子进程创建 和 父子进程运行的问题

1.我们写的代码通过fork()系统调用接口让操作系统按父进程为模板复制一个子进程的PCB(Linux中是task_struct),几乎所有的字段都复制进来,但是也有私有的,比如PID
2.子进程创建后,fork()以下的代码都是父子进程共享的,所以我们需要用分支语句来控制父子进程执行不同的行为
3.每个CPU都会给自己维护一个运行队列run_queue,队列中就是进程控制块task_struct,所以进程进行的过程也就是挑选一个进程控制块来运行
4.父子进程运行的先后是不确定的,因为CPU不是一直执行某一个执行,会抢占和退让,这由调度算法决定

总结

进程的创建过程也是非常重要的,希望打家掌握清楚这些细节,同时,下一期更新进程的状态,谢谢大家一直以来的支持!!

在这里插入图片描述