计算机系统基础之第八章:17个fork()函数

本文详细剖析了计算机系统中多进程的创建,通过17个具体的fork()函数实例,深入讲解了其运行结果和分析,涵盖了进程的生成、交互、僵死和孤儿状态,以及异常控制流对程序的影响。通过示例代码,阐述了父进程与子进程之间的关系和行为差异,同时探讨了如何处理僵死和孤儿进程,以及使用Ctrl+C和Ctrl+Z对程序的不同影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本章学习要点

通过第八章——异常控制流中接触到了进程的概念。而其中的fork()函数是本章的难点也是重点。接下来我们一起分析下这17个fork()函数


1、fork1()

代码如下(示例):

void fork1()
{
    int x = 1;
    pid_t pid = fork();

    if (pid == 0) {
	printf("Child has x = %d\n", ++x);
    } 
    else {
	printf("Parent has x = %d\n", --x);
    }
    printf("Bye from process %d with x = %d\n", getpid(), x);
}

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 1
Parent has x = 0
Bye from process 2456 with x = 0
chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ Child has x = 2
Bye from process 2457 with x = 2

分析

如果是子进程,就执行自加,输出:2,然后输出子进程的进程号;如果是父进程,就输出自减,输出:0,然后输出父进程的进程号。父进程与子进程不会相互影响。

2、fork2()

代码如下(示例):

void fork2()
{
    printf("L0\n");
    fork();
    printf("L1\n");    
    fork();
    printf("Bye\n");
}

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 2
L0
L1
L1
chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ Bye
Bye
Bye
Bye

3、fork3()

代码如下(示例):

void fork3()
{
    printf("L0\n");
    fork();
    printf("L1\n");    
    fork();
    printf("L2\n");    
    fork();
    printf("Bye\n");
}

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 3
L0
L1
L1
L2
Bye
chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ L2
Bye
Bye
Bye
Bye
Bye
L2
L2
Bye
Bye

分析

fork3和fork2同理,父进程生成子进程又fork()生成子进程,即会输出1个L0,2个L1,4个L2,8个Bye。

4、fork4()

代码如下(示例):

void fork4()
{
    printf("L0\n");
    if (fork() != 0) {
		printf("L1\n");    
		if (fork() != 0) {
		    printf("L2\n");
		}
    }
    printf("Bye\n");
}

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 4
L0
L1
L2
Bye
chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ Bye
Bye

分析

父进程fork()后输出字符再继续fork(),子进程输出Bye。

5、fork5()

代码如下(示例):

void fork5()
{
    printf("L0\n");
    if (fork() == 0) {
		printf("L1\n");    
		if (fork() == 0) {
		    printf("L2\n");
		}
    }
    printf("Bye\n");
}

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 5
L0
Bye
chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ L1
Bye
L2
Bye

6、fork6()

代码如下(示例):

void cleanup(void) {
    printf("Cleaning up\n");
}

void fork6()
{
    atexit(cleanup);
    fork();
    exit(0);
}

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 6
Cleaning up
chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ Cleaning up

7、fork7()

代码如下(示例):

void fork7()
{
    if (fork() == 0) {
	/* Child */
		printf("Terminating Child, PID = %d\n", getpid());
		exit(0);
	    } 
	else {
		printf("Running Parent, PID = %d\n", getpid());
		while (1)
		    ; /* Infinite loop */
	}
}

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 7
Running Parent, PID = 2365
Terminating Child, PID = 2366

分析

该子进程即为“僵死进程”。

8、fork8()

代码如下(示例):

void fork8()
{
    if (fork() == 0) {
	/* Child */
		printf("Running Child, PID = %d\n",getpid());
	while (1)
	    ; /* Infinite loop */
    }
    else {
		printf("Terminating Parent, PID = %d\n",getpid());
		exit(0);
    }
}

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 8
Terminating Parent, PID = 2228
chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ Running Child, PID = 2227

分析

该子进程即为“孤儿进程”。

9、fork9()

代码如下(示例):

void fork9()
{
    int child_status;

    if (fork() == 0) {
		printf("HC: hello from child\n");
        exit(0);
    } 
    else {
		printf("HP: hello from parent\n");
		wait(&child_status);
		printf("CT: child has terminated\n");
    }
    printf("Bye\n");
}

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 9
HP: hello from parent
HC: hello from child
CT: child has terminated
Bye

10、fork10()

代码如下(示例):

void fork10()
{
    pid_t pid[N];
    int i, child_status;

    for (i = 0; i < N; i++)
	if ((pid[i] = fork()) == 0) {
	    exit(100+i); /* Child */
	}
    for (i = 0; i < N; i++) { /* Parent */
		pid_t wpid = wait(&child_status);
		if (WIFEXITED(child_status))
		    printf("Child %d terminated with exit status %d\n",wpid, WEXITSTATUS(child_status));
		else
		    printf("Child %d terminate abnormally\n", wpid);
    }
}

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 10
Child 2510 terminated with exit status 104
Child 2509 terminated with exit status 103
Child 2508 terminated with exit status 102
Child 2507 terminated with exit status 101
Child 2506 terminated with exit status 100

分析

这5句输出不一定会按顺序。

11、fork11()

代码如下(示例):

void fork11()
{
    pid_t pid[N];
    int i;
    int child_status;

    for (i = 0; i < N; i++)
	if ((pid[i] = fork()) == 0)
	    exit(100+i); /* Child */
    for (i = N-1; i >= 0; i--) {
	pid_t wpid = waitpid(pid[i], &child_status, 0);
	if (WIFEXITED(child_status))
	    printf("Child %d terminated with exit status %d\n",
		   wpid, WEXITSTATUS(child_status));
	else
	    printf("Child %d terminate abnormally\n", wpid);
    }
}

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 11
Child 2545 terminated with exit status 104
Child 2544 terminated with exit status 103
Child 2543 terminated with exit status 102
Child 2542 terminated with exit status 101
Child 2541 terminated with exit status 100
chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$

分析

这5句输出一定会按顺序。

12、fork12()

代码如下(示例):

void fork12()
{
    pid_t pid[N];
    int i;
    int child_status;

    for (i = 0; i < N; i++)
	if ((pid[i] = fork()) == 0) {
	    /* Child: Infinite Loop */
	    while(1)
		;
	}
    for (i = 0; i < N; i++) {
		printf("Killing process %d\n", pid[i]);
		kill(pid[i], SIGINT);
    }

    for (i = 0; i < N; i++) {
		pid_t wpid = wait(&child_status);
		if (WIFEXITED(child_status))
	  	  	printf("Child %d terminated with exit status %d\n",
		   	wpid, WEXITSTATUS(child_status));
		else
	   	    printf("Child %d terminated abnormally\n", wpid);
    }
}

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 12
Killing process 2245
Killing process 2246
Killing process 2247
Killing process 2248
Killing process 2249
Child 2247 terminated abnormally
Child 2248 terminated abnormally
Child 2245 terminated abnormally
Child 2249 terminated abnormally
Child 2246 terminated abnormally
chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$

13、fork13()

代码如下(示例):

void fork13()
{
    pid_t pid[N];
    int i;
    int child_status;

    signal(SIGINT, int_handler);
    for (i = 0; i < N; i++)
	if ((pid[i] = fork()) == 0) {
	    /* Child: Infinite Loop */
	    while(1)
		;
	}

    for (i = 0; i < N; i++) {
	printf("Killing process %d\n", pid[i]);
	kill(pid[i], SIGINT);
    }

    for (i = 0; i < N; i++) {
	pid_t wpid = wait(&child_status);
	if (WIFEXITED(child_status))
	    printf("Child %d terminated with exit status %d\n",
		   wpid, WEXITSTATUS(child_status));
	else
	    printf("Child %d terminated abnormally\n", wpid);
    }
}

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 13
Killing process 2391
Killing process 2392
Killing process 2393
Killing process 2394
Killing process 2395
Process 2395 received signal 2
Child 2395 terminated with exit status 0
Process 2394 received signal 2
Child 2394 terminated with exit status 0
Process 2393 received signal 2
Child 2393 terminated with exit status 0
Process 2392 received signal 2
Child 2392 terminated with exit status 0
Process 2391 received signal 2
Child 2391 terminated with exit status 0
chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$

14、fork14()

代码如下(示例):

int ccount = 0;
void child_handler(int sig)
{
    int child_status;
    pid_t pid = wait(&child_status);
    ccount--;
    printf("Received SIGCHLD signal %d for process %d\n", sig, pid); /* Unsafe */
    fflush(stdout); /* Unsafe */
}

void fork14()
{
    pid_t pid[N];
    int i;
    ccount = N;
    signal(SIGCHLD, child_handler);

    for (i = 0; i < N; i++) {
	if ((pid[i] = fork()) == 0) {
	    sleep(1);
	    exit(0);  /* Child: Exit */
	}
    }
    while (ccount > 0)
    ;
}

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 14
Received SIGCHLD signal 17 for process 2941
Received SIGCHLD signal 17 for process 2942
Received SIGCHLD signal 17 for process 2943
Received SIGCHLD signal 17 for process 2944

15、fork15()

代码如下(示例):

void child_handler2(int sig)
{
    int child_status;
    pid_t pid;
    while ((pid = wait(&child_status)) > 0) {
	ccount--;
	printf("Received signal %d from process %d\n", sig, pid); /* Unsafe */
	fflush(stdout); /* Unsafe */
    }
}

void fork15()
{
    pid_t pid[N];
    int i;
    ccount = N;

    signal(SIGCHLD, child_handler2);

    for (i = 0; i < N; i++)
	if ((pid[i] = fork()) == 0) {
	    sleep(1);
	    exit(0); /* Child: Exit */

	}
    while (ccount > 0) {
	pause();
    }
}

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 15
Received signal 17 from process 3054
Received signal 17 from process 3053
Received signal 17 from process 3052
Received signal 17 from process 3051
Received signal 17 from process 3050
chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$

16、fork16()

代码如下(示例):

void fork16() 
{
    if (fork() == 0) {
		printf("Child1: pid=%d pgrp=%d\n",getpid(), getpgrp());
		if (fork() == 0)
	   	   printf("Child2: pid=%d pgrp=%d\n",getpid(), getpgrp());
	while(1);
    }
} 

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 16
chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ Child1: pid=2509 pgrp=2508
Child2: pid=2509 pgrp=2508

17、fork17()

代码如下(示例):

void fork17() 
{
    if (fork() == 0) {
	printf("Child: pid=%d pgrp=%d\n",
	       getpid(), getpgrp());
    }
    else {
	printf("Parent: pid=%d pgrp=%d\n",
	       getpid(), getpgrp());
    }
    while(1);
} 

运行结果

chaoge@chaoge-virtual-machine:/mnt/hgfs/chap8_code$ ./forks 17
Parent: pid=2271 pgrp=2271
Child: pid=2272 pgrp=2271

分析

fork17是想让我们知道ctrl+c 和+z的区别。
Ctrl+c会直接终止程序,通过ps可以发现死循环的僵死程序被清除了,
Ctrl + z会挂起程序,通过ps会发现僵死程序还在,还需要通过kill -9来杀死它们。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值