这周先学了进程环境和进程操作,对于什么是进程有大致的一个了解,但是没有真正的明白到底什么是进程。在进程控制这一章一开始学习的时候,在尽力的去理解什么是进程,我理解的进程就是功能性的函数一样,每实现一个功能叫做一个进程,也可以说是叫做过程,是比较具体的过程。
第一个问题:
第11章进程管理的第一个示例程序就是打印当前进程的进程ID,代码如下:
1 #include <stdio.h> 2 3 #include <unistd.h> 4 5 int main() 6 7 { 8 9 pid_t pid, ppid, uid, euid, gid, egid; 10 11 pid = getpid(); /* 得到进程ID */ 12 13 ppid = getppid(); /* 得到父进程ID */ 14 15 uid = getuid(); /* 得到用户ID */ 16 17 euid = geteuid(); /* 得到有效用户ID */ 18 19 gid = getgid(); /* 得到组ID */ 20 21 egid = getegid(); /* 得到有效组ID */ 22 23 printf("id of current process : %u\n", pid); /* pid_t实际上是无符号整型, 24 25 所以使用%u而不是%d */ 26 27 printf("parent id of current process : %u\n", ppid); 28 29 printf("user id of current process : %u\n", uid); 30 31 printf("effective user id of current process : %u\n", euid); 32 33 printf("group id of current process : %u\n", gid); 34 35 printf("effective group id of current process : %u\n", egid); 36 37 return 0; 38 39 }
运行结果:
运行结果可以看出来,每次运行这个程序的时候发现,子进程的ID每次加1,而其他的进程ID都没有变化。上图中也可以发现子进程的ID是每次加1,后来我在调试的时候,又重新编译再运行的结果如下图:
这个图中看出来重新编译之后与之前相比,进程ID不止是加1,再对比之前的规律来说,就是这次进程ID加了8可能是跟中间运行gcc pid.c –o app这条指令有关。接下来有进行测试。结果显示,一个ls指令也是占了一个进程,因此会打印进程ID加2。
后来再做了测试,发现,运行一次程序之后,过一会再运行的话进程ID也会有很大的变化,我觉得这个ID变化比较大的原因是在这个时间间隔内系统内有其他的进程运行的结果。
回头看gcc pid.c –o app这条指令之后再运行程序,进程ID的变化是6,后来我有测试了几次,发现每次间隔都是6。
这三次测试中发现,每一次重新编译之后在运行程序,进程ID的间隔都是6,这说明gcc –o pid.c app这条指令用了6个进程。再回到之前学习的gcc编译流程来看,gcc编译的过程4步,先将.c文件预处理.i文件,再将.i文件编译成汇编语言生成.s文件,再将.s文件经过汇编生成目标文件.o文件,最后将.o文件链接起来生成.exe文件,最后运行。从.c文件到.exe文件经过了4个过程,但是这个过程占用了6个进程,这4个过程中是不是有的过程占用了1到2个进程?
第二个问题:
打印父进程和子进程的进程ID程序如下:
1 #include <stdio.h> 2 3 #include <stdlib.h> 4 5 #include <unistd.h> 6 7 int main(void) 8 9 { 10 11 pid_t pid; /* 保存进程ID */ 12 13 pid = fork(); /* 创建一个新进程 */ 14 15 if(pid < 0){ /* fork出错 */ 16 17 printf("fail to fork\n"); 18 19 exit(1); 20 21 }else if(pid == 0){ /* 子进程 */ 22 23 printf("this is child, pid is : %u\n", getpid()); 24 25 /* 打印子进程的进程ID */ 26 27 }else{ 28 29 printf("this is parent, pid is : %u, child-pid is : %u\n", getpid(), 30 31 pid); /* 打印父进程和其子进程的进程ID */ 32 33 } 34 35 return 0; 36 37 }
这个代码的运行结果是:
根据运行结果发现,先打印的是父进程的进程ID,再打印子进程的进程ID。为什么pid会等于0。书上说的是“对于子进程,fork()函数返回0。由于系统的0号进程是内核进程,所以子进程的进程号不可能是0,由此区别父进程和子进程”,这句话跟这个程序结合起来有点不太理解,pid等于0才能执行“printf("this is child, pid is : %u\n", getpid());”这句话,但是程序中pid执行了这句话,是不是说明这里的pid等于0,那这个pid的值为什么等于0?