linux环境高级编程之fork、getpid、getppid函数
来源:互联网 发布:诺基亚5310xm软件 编辑:程序博客网 时间:2024/05/02 04:25
前段时间学习了fork函数创建进程,在fork创建后用execl函数来执行linux下的命令。
fork函数()
一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。
一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。
用man fork 在linux下查看fork的用法
#include <unistd.h> pid_t fork(void);
fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
1)在父进程中,fork返回新创建子进程的进程ID;
2)在子进程中,fork返回0;
3)如果出现错误,fork返回一个负值;
我们可以通过fork返回的值来判断当前进程是子进程还是父进程。
fpid的值为什么在父子进程中不同。“其实就相当于链表,进程形成了链表,父进程的fpid(p 意味point)指向子进程的进程id, 因为子进程没有子进程,所以其fpid为0.
getpid用来获取当前进程ID
getppid用来获取当前进程的父进程的ID
用法:
#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
我写了一段代码用来加深理解
[fanmaolin@Centeros duojincheng]$ vim testfork.c 1 /********************************************************************************* 2 * Copyright: (C) 2017 fanmaolin<fanmaolinn@gmail.com> 3 * All rights reserved. 4 * 5 * Filename: testfork.c 6 * Description: This file 7 * 8 * Version: 1.0.0(05/09/2017) 9 * Author: fanmaolin <fanmaolinn@gmail.com> 10 * ChangeLog: 1, Release initial version on "05/09/2017 07:28:18 PM" 11 * testfork.c 12 ********************************************************************************/ 13 14 #include <sys/types.h> 15 #include <unistd.h> 16 #include <stdio.h> 17 int main () 18 { 19 pid_t fpid=fork(); //fpid表示fork函数返回的值 20 int count=0; 21 22 if (fpid < 0) 23 printf("error in fork!"); 24 else if (fpid == 0) 25 { 26 printf("我是子进程\n"); 27 printf("i am the child process, my process id is %d\n",getpid()); 28 printf("My Parents's process id is %d\n",getppid()); 29 count++; 30 } 31 else 32 { 33 printf("我是父进程\n"); 34 printf("i am the parent process, my process id is %d\n",getpid()); 35 count++; 36 sleep(1);//因为不确定父子进程谁会先执行,加个延时保证父进程先执行 37 } 38 printf("统计结果是: %d\n",count); 39 return 0; 40 }
执行结果
可以看到父进程ID为65869
子进程ID为65870
从子进程用getppid()获取父进程ID为65869
返回两次统计结果:1
父子进程间不确定谁会先执行。
问题总结:
关于为什么这里会返回两次1呢?
当父进程在执行的过程中,执行到sleep(1)时CPU分配给父进程的时间片到了,这时会执行子进程,执行完子进程后再来执行父进程,所以两个1是并列打印的,下面我们来看一下去掉sleep(1)的执行结果。
36 #ifdef SLEEP 37 sleep(1); 38 #endif
在这里有个技巧,因为有时我会用到sleep(1)有时又不会用到,加一个宏定义,如果我想用sleep时,
[fanmaolin@Centeros duojincheng]$ gcc testfork.c -o DSLEEP
[fanmaolin@Centeros duojincheng]$ ./a.out
我是父进程
i am the parent process, my process id is 66512
我是子进程
i am the child process, my process id is 66513
My Parents's process id is 66512
统计结果是: 1
统计结果是: 1
我是父进程
i am the parent process, my process id is 66512
我是子进程
i am the child process, my process id is 66513
My Parents's process id is 66512
统计结果是: 1
统计结果是: 1
如果我不想用sleep时
[fanmaolin@Centeros duojincheng]$ gcc testfork.c
[fanmaolin@Centeros duojincheng]$ ./a.out
我是父进程
i am the parent process, my process id is 66527
统计结果是: 1
[fanmaolin@Centeros duojincheng]$ 我是子进程
i am the child process, my process id is 66528
My Parents's process id is 1
统计结果是: 1
[fanmaolin@Centeros duojincheng]$ ./a.out
我是父进程
i am the parent process, my process id is 66527
统计结果是: 1
[fanmaolin@Centeros duojincheng]$ 我是子进程
i am the child process, my process id is 66528
My Parents's process id is 1
统计结果是: 1
看深红色字体,没有用sleep时的执行结果,会发现My Parents's process id is 1
子进程的父进程ID变成了“1”,这是为什么呢?
我们来看一下,哪一个进程的ID是1
[fanmaolin@Centeros duojincheng]$ ps auxUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMANDroot 1 0.0 0.1 19364 1264 ? Ss May08 0:03 /sbin/init
init进程的ID是1,原来我们不用sleep时,CPU如果先执行了父进程,父进程很快执行完了,子进程执行的时候没有了父进程,变成了孤儿进程,这个时候就被init进程收养了,所以子进程的父进程就变成了init进程。
在使用子进程的时候还要注意避免出现“僵尸进程”,所以要在父进程里给子进程“收尸”wait.
在分析类似问题时,一定要考虑到CPU时切片运行的,它留给每个程序的时间是有限的,差不多是ms级。
参考:
http://blog.csdn.net/jason314/article/details/5640969fork
http://www.cnblogs.com/wannable/p/6021617.html 孤儿进程、僵尸进程、守护进程
阅读全文
0 0
- linux环境高级编程之fork、getpid、getppid函数
- Linux系统调用--getpid/getppid函数详解
- Linux系统调用--getpid/getppid函数详解
- Linux系统调用--getpid/getppid函数详解
- pid=fork();getpid() 和getppid()
- 4进程原语:fork()函数,getpid()函数和getppid()函数,getuid()函数,getgid()函数,vfork()
- 进程原语:fork()函数,getpid()函数和getppid()函数,getuid()函数,getgid()函数,vfork()
- (三)和菜鸟一起学习unix之创建进程 fork getpid getppid
- getpid,getppid
- linux-进程控制-getpid、getppid、…
- linux下的四个简单函数介绍:getpid, getppid, getuid, getgid
- linux环境编程之 fork() || fork()
- Linux 进程控制--- 编程 --- getpid --- fork --- exec --- system --- wait
- getpid/getppid系统调用
- GetPid/GetPPid系统调用
- getpid/getppid系统调用
- 观察getpid和getppid
- getpid/getppid系统调用
- 在Node.js中实现文件复制的方法和实例
- contenteditable="true"的div事件处理
- 经典Prim算法题目及代码
- 机器学习深度学习基础笔记(4)——Backpropagation算法实现
- 安卓中MVC模式的深度思索和实践(三)
- linux环境高级编程之fork、getpid、getppid函数
- 关于jquery中toggle()方法的替换
- 六大数据采集工具
- 两个CentOS系统之间的NFS网络文件系统使用
- Python json dumps() && loads()
- ORA-12541:TNS:无监听程序
- 如何在SugarCRM添加一个自定义Dashlet?
- Android 生命周期
- 排序算法对比