#include
pid_t fork(void);
fork()
函数被调用后会立即创建一个子进程,子进程和父进程独立运行互不干扰
返回值:在父进程中返回一个大于0的数,表示创建的子进程的id;在子进程中返回 0;-1表示创建失败。
#include
pid_t getpid(void); // 获取当前进程的pid
pid_t getppid(void); // 获取当前进程父进程的pid
#include
uid_t getuid(void); // 获取当前进程实际使用的用户id
uid_t geteuid(void); // 获取当前进程原本有效的用户id
补充:
区分一个函数是“系统函数”还是“库函数”依据:
① 是否访问内核数据结构
② 是否访问外部硬件资源
二者有任一 则为系统函数,二者均无 则为库函数;
#include
gid_t getgid(void); // 获取当前进程使用用户组id
gid_t getegid(void); // 获取当前进程原本有效用户组id
1 #include <stdio.h>
2 #include <unistd.h>
3
4 int main(void)
5 {
6 pid_t pid = fork();
7 if(pid == 0){
8 printf("I'm subProcess, my pid = %d, ppid = %d\n", getpid(), getppid());
9 }else if(pid > 0){
10 printf("I'm parentProcess, my pid = %d, ppid = %d\n", getpid(), getppid());
11 sleep(1); // Avoid father dying in front of son
12 }else{
13 printf("fork error!\n");
14 }
15 return 0;
16 }
执行结果:
I'm parentProcess, my pid = 12050, ppid = 11620
I'm subProcess, my pid = 12051, ppid = 12050
下面以创建6个子进程为例:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4
5 int main(void)
6 {
7 int i = 0;
8 pid_t pid;
9
10 printf("I'm start parent, pid = %d, ppid = %d\n", getpid(), getppid());
11 for(;i < 6; i++)
12 {
13 pid = fork();
14 if(pid == 0)
15 {
16 //printf("Subprocess do something. I'm pid = %d, ppid = %d\n", getpid(), getppid());
17 break; // 要创建6个子进程这里就必须break跳出,否则子进程又会继续创建子进程,结果就会创建 2^6 - 1个子进程
18 }else if(pid <0){
19 perror("fork error!");
20 exit(1);
21 }
22 //printf("I'm parent, pid = %d, ppid = %d, cpid = %d\n", getpid(), getppid(), pid);
23 //sleep(1); // 防止父进程先结束,因为父进程先结束的话子进程的ppid就会等于1
24 }
25 // 上面注释掉的语句与下面26-30行的语句等效,只是移除循环执行而已
26 if(i < 6)
27 printf("Subprocess do something. I'm pid = %d, ppid = %d\n", getpid(), getppid());
28 if(i == 6)
29 printf("I'm parent, pid = %d, ppid = %d\n", getpid(), getppid());
30 sleep(1);
31 return 0;
32 }
执行结果:
I'm start parent, pid = 12115, ppid = 11620
I'm parent, pid = 12115, ppid = 11620
Subprocess do something. I'm pid = 12121, ppid = 12115
Subprocess do something. I'm pid = 12119, ppid = 12115
Subprocess do something. I'm pid = 12120, ppid = 12115
Subprocess do something. I'm pid = 12118, ppid = 12115
Subprocess do something. I'm pid = 12117, ppid = 12115
Subprocess do something. I'm pid = 12116, ppid = 12115
补充:
当我们在对含有fork的程序进行调试的时候是跟踪父进程还是子进程呢?
默认是跟踪父进程,如果需要跟踪子进程则需要**gdb
调试时在调用fork
函数之前**执行下面相应的命令:
set follow-fork-mode child # 设置gdb在fork之后跟踪子进程。
set follow-fork-mode parent # 设置跟踪父进程。
注意,一定要在fork
函数调用之前设置才有效。