🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸
文章目录
getpid、getppid与fork1.getpid准备2.getpid应用3. 结束进程4.getppid准备5.getppid应用6.bash与操作系统7. 通过代码创建子进程 fork8.子进程创建 和 父子进程运行的问题总结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不是一直执行某一个执行,会抢占和退让,这由调度算法决定
总结
进程的创建过程也是非常重要的,希望打家掌握清楚这些细节,同时,下一期更新进程的状态,谢谢大家一直以来的支持!!