《网络编程》-第10章 – 多进程服务端

具有代表性的并发服务器端实现模型:

​ 多进程服务器:通过创建多个进程提供服务;

​ 多路复用服务器:通过捆绑并统一管理I/O对象提供服务;

​ 多线程服务器:通过生成与客户端等量的线程提供服务。

1、进程

fork() 函数

#include <unistd.h>

pid_t fork();

功能:

​ 创建一个进程。

返回值:

失败,返回-1; 成功,返回进程ID;

父进程: fork() 函数返回子进程ID;

子进程: fork() 函数返回0。

2、僵尸进程

​ 子进程运行完后,父进程并未对其回收。

验证僵尸进程:

// 在 fork() 后程序会先运行子进程然后父进程。

// 在本程序中,父进程 sleep(30); 在这个过程中子进程未被回收,而成为了僵尸进程。

// 在 这30s 过程中,打开一个新的终端 ps aux 在 sta栏内会看到一个进程的状态为 Z+, 就是此僵尸进程。

(代码: unit_10_zombie.c)

在这里插入图片描述

30s后:

在这里插入图片描述

3、回收子进程

​ 如果子进程未得到得到回收,就会变成僵尸进程。

利用 wait() 函数

#include <sys/wait.h>

pid_t wait( int *statloc );

功能:

​ 回收终止的进程。

【注】若此时没有进程终止,会阻塞等待,知道有进程终止。

参数:

statloc: (被终止)进程的状态,一般就定义 int 型变量,然后取其地址。

返回值:

​ 成功,返回终止的子进程 ID; 失败,返回 -1。

【补】

WIFEXITED() 函数

子进程正常终止返回“真”(TRUE)。

​ eg. if( WIFEXITED() )

WEXITSTATUS() 函数

​ 返回子进程的返回值。指的是 return 或者 exit()返回值。

​ 【注】 exit() 别用0,1。

利用 waitpid() 函数

#include <sys.wait.h>

pid_t waitpid( pid_t pid, int *statloc, int options );

功能:

回收终止的进程,且不会阻塞。

参数:

​ pid:等待终止的目标子进程的ID。

​ 若传递 -1, 则与 wait() 函数相同,可以等待任意子进程终止。

​ statloc:(被终止)进程的状态,一般就定义 int 型变量,然后取其地址。

​ options:一般写 WNOHANG,效果:即使没有终止的子进程也不会进入阻塞状态,而是返回0并退出函数。

返回值:

​ 成功,返回终止的子进程ID(或0); 失败,返回 -1。

3、信号处理

​ 信号处理:在特定事件发生时由操作系统向进程发送的消息,然后今天处理。

【补】结构体 sigaction

struct sigaction

{

​ void (&sa_handler) (int); // 指向信号触发的时候调用的函数。Eg.进程回收函数

​ sigset_t mask; // 到时候用sigemptyset( &act.sa_mask )初始化

​ int sa_flags; // 直接写0

}

sigaction() 函数

#include <signal.h>

int sigaction( int signo, const struct sigaction act, struct sigaction oldact );

功能:

利用 sigaction() 函数进行信号处理操作。

参数:

​ signo: 对应不同的信号状态:

在这里插入图片描述

​ act: 对应于参数 signo 的信号处理信息。(对应结构体如下)

​ oldact:直接写0。

返回值

成功,返回0; 失败,返回 -1。

eg.实例

​ // 使用信号回收僵尸进程

​ struct sigaction act;

​ act.sa_handler = recycle; // 回收函数 recycle 自己写

​ act.sa_flags = 0;

​ sigemptyset( &act.sa_mask );

​ sigaction( SIGCHLD, &act, NULL );

详情参考 unit_10_remove_zombie.c 利用信号处理技术消灭僵尸进程。

4、基于多任务的并发服务器

​ 此节的案例相当重要。

5、分割TCP的I/O程序

代码入口

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页