《TCP/IP网络编程》第 10 章 多进程服务器端 笔记

第 10 章 多进程服务器端
本章代码,在TCP-IP-中可以找到 。
10.1 进程概念及应用 10.1.1 并发服务端的实现方法
通过改进服务端,使其同时向所有发起请求的客户端提供服务,以提高平均满意度 。而且,网络程序中数据通信时间比 CPU 运算时间占比更大,因此,向多个客户端提供服务是一种有效的利用 CPU 的方式 。接下来讨论同时向多个客户端提供服务的并发服务器端 。下面列出的是具有代表性的并发服务端的实现模型和方法:
先是第一种方法:多进程服务器
10.1.2 理解进程
进程的定义如下:
占用内存空间的正在运行的程序
假如你下载了一个游戏到电脑上,此时的游戏不是进程,而是程序 。只有当游戏被加载到主内存并进入运行状态,这是才可称为进程 。
10.1.3 进程 ID
在说进程创建方法之前,先要简要说明进程 ID 。无论进程是如何创建的,所有的进程都会被操作系统分配一个 ID 。此 ID 被称为「进程ID」,其值为大于 2 的证书 。1 要分配给操作系统启动后的(用于协助操作系统)首个进程,因此用户无法得到 ID 值为 1。接下来观察在 Linux 中运行的进程 。
ps au
【《TCP/IP网络编程》第 10 章 多进程服务器端 笔记】通过上面的命令可查看当前运行的所有进程 。需要注意的是,该命令同时列出了 PID(进程ID) 。参数 a 和 u列出了所有进程的详细信息 。

《TCP/IP网络编程》第 10 章 多进程服务器端 笔记

文章插图
10.1.4 通过调用 fork 函数创建进程
创建进程的方式很多,此处只介绍用于创建多进程服务端的 fork 函数 。
#include pid_t fork(void);// 成功时返回进程ID,失败时返回 -1
fork 函数将创建调用的进程副本 。也就是说,并非根据完全不同的程序创建进程,而是复制正在运行的、调用 fork 函数的进程 。另外,两个进程都执行 fork 函数调用后的语句(准确的说是在 fork 函数返回后) 。但因为是通过同一个进程、复制相同的内存空间,之后的程序流要根据 fork 函数的返回值加以区分 。即利用 fork 函数的如下特点区分程序执行流程 。
此处,「父进程」( )指原进程,即调用 fork 函数的主体,而「子进程」(Child )是通过父进程调用 fork 函数复制出的进程 。接下来是调用 fork 函数后的程序运行流程 。如图所示:
《TCP/IP网络编程》第 10 章 多进程服务器端 笔记

文章插图
从图中可以看出,父进程调用 fork 函数的同时复制出子进程,并分别得到 fork 函数的返回值 。但复制前,父进程将全局变量 gval 增加到 11,将局部变量 lval 的值增加到 25,因此在这种状态下完成进程复制 。复制完成后根据 fork 函数的返回类型区分父子进程 。父进程的 lval 的值增加 1 ,但这不会影响子进程的 lval 值 。同样子进程将 gval 的值增加 1 也不会影响到父进程的 gval。因为 fork 函数调用后分成了完全不同的进程,只是二者共享同一段代码而已 。接下来给出一个例子:
#include #include int gval = 10;int main(int argc, char *argv[]){pid_t pid;int lval = 20;gval++, lval += 5;pid = fork();if (pid == 0)gval += 2, lval += 2;elsegval -= 2, lval -= 2;if (pid == 0)printf("Child Proc: [%d,%d] \n", gval, lval);elseprintf("Parent Proc: [%d,%d] \n", gval, lval);return 0;}
编译运行:
gcc fork.c -o fork./fork
运行结果: