进程
Linux下C语言进程相关的函数主要有:
函数 | 说明 |
---|---|
getpid() | 获取当前进程ID |
getppid() | 获取父进程ID |
getpgrp() | 获取进程组ID |
fork() | 创建子进程 |
wait() | 等待子进程结束 |
fork()函数是Linux系统下C语言用来创建子进程的函数。最简单的用法如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <stdio.h>
#include <unistd.h>
int main(void){
pid_t pid;
pid=fork();
printf("%d->%d\n",getpid(),pid);
}
/*
执行结果:
14929->14930
14930->0
*/
可以看到,fork()函数后的printf函数,执行了两次,一次是在进程ID为14920的进程中,打印pid的值为14930。另一次是在进程ID为14930的进程中,打印了0。
这就是fork()函数的用法,它会在程序中返回两次,在父进程中的返回值是子进程的进程ID,子进程中返回0,如此便可区分父、子进程。可以利用这个原理设计一个双进程的程序:
1 | #include <stdio.h> |
在此例中,程序是以双进程的方式在系统中执行的。并且父进程比子进程执行时间短,所以父进程先结束,子进程在父进程退出后,仍然在控制台打印出信息,是因为在父进程退出后,子进程会交由系统接管,此时子进程的父进程ID变成了一个系统进程(systemd或者init)。
多进程
C语言多进程Fork实例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void){
int i=0;
for(i=0;i<3;i++){
pid_t fpid = fork();
if(fpid==0)
printf("\tSon: %d (%d)\n",getpid(),getppid());
else
wait(0);
printf("Father: %d (%d)\n",getpid(),getppid());
}
return 0;
}
/*
执行结果:
Son: 16013 (16012)
Father: 16013 (16012)
Son: 16014 (16013)
Father: 16014 (16013)
Son: 16015 (16014)
Father: 16015 (16014)
Father: 16014 (16013)
Father: 16013 (16012)
Son: 16016 (16013)
Father: 16016 (16013)
Father: 16013 (16012)
Father: 16012 (3595)
Son: 16017 (16012)
Father: 16017 (16012)
Son: 16018 (16017)
Father: 16018 (16017)
Father: 16017 (16012)
Father: 16012 (3595)
Son: 16019 (16012)
Father: 16019 (16012)
Father: 16012 (3595)
*/
一个完整的多进程示例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int sub_func(int sec){
printf("\tProcess:%d, ParentProcess(%d), sec(%d)\n",getpid(),getppid(),sec);
sleep(sec);
return 0;
}
int main(void){
int i=0;
printf("Father: %d (%d)\n",getpid(),getppid());
for(i=0;i<3;i++){
pid_t fpid = fork();
if(fpid==0){
sub_func(i);
}else{
wait(&fpid);
}
}
return 0;
}
/*
编译:gcc -m32 -o test test.c && ./test
执行结果:
Father: 18081 (3595)
Process:18082, ParentProcess(18081), sec(0)
Process:18083, ParentProcess(18082), sec(1)
Process:18084, ParentProcess(18083), sec(2)
Process:18088, ParentProcess(18082), sec(2)
Process:18089, ParentProcess(18081), sec(1)
Process:18090, ParentProcess(18089), sec(2)
Process:18091, ParentProcess(18081), sec(2)
*/