互联网络程序设计第4章

上传人:ji****72 文档编号:48560652 上传时间:2018-07-17 格式:PPT 页数:42 大小:680KB
返回 下载 相关 举报
互联网络程序设计第4章_第1页
第1页 / 共42页
互联网络程序设计第4章_第2页
第2页 / 共42页
互联网络程序设计第4章_第3页
第3页 / 共42页
互联网络程序设计第4章_第4页
第4页 / 共42页
互联网络程序设计第4章_第5页
第5页 / 共42页
点击查看更多>>
资源描述

《互联网络程序设计第4章》由会员分享,可在线阅读,更多相关《互联网络程序设计第4章(42页珍藏版)》请在金锄头文库上搜索。

1、第四章、多进程并发服务器n多进程并发服务器模型 n进程与fork函数 n第1版多进程并发服务器 n信号机制与Wait函数 n第2版多进程并发服务器 n测试用例1. 多进程并发服务器模型n 迭代服务器的缺陷 Chap3.echo测试用 例中,多用户的情况 连接建立后,没有 accept,连接在哪里 ? 这是功能上的一个缺 陷n Why? listen函数队列 accept从已完成队列 的对头摘取新套接字 对客户端的服务是一 个串行的过程Bind Addr.ListenAccept Conn.ProcessClose conn.Accept Req.Process Req.ResponseTCP

2、Iterative servern 多进程并发服务模型 采用多进程的方式引 入并行 目的是:使得每个客 户端都能够得到一个 进程的服务 进程与fork函数Bind Addr.ListenAccept ConnForkClose connected conn. Process Conn.Close connected conn.ExitClose Listening Conn.Server (parent)TCP Concurrent ServerServer (child)2. 进程与fork函数n 进程的概念 在传统的操作系统中,进程是资源的所有者,是CPU 时间片调度的基本单位 在现代操作

3、系统中,引入线程概念后。进程弱化为资 源的所有者,而线程称为调度的基本单元,一个进程 可以容纳多个线程。 本章采用一个进程内只含有一个线程的模型 n 关于Unix进程的基本操作与模型,请参考Unix环境高 级编程一书,本章并不展开。 n 进程的创建,需要调用fork函数fork函数n 函数原型 #include pid_t fork(void); n fork系统调用创建了一个子进程,子进程基本上是父进 程的一个拷贝,这包括可执行代码、堆栈、堆等。 Unix通常采用copy-on-write的方式实现fork,父 子进程通过共享虚拟内存的页表,只有当父子进程修 改它的页表时,才会做拷贝动作。

4、子进程会继承父进程打开的文件描述符,还会父进程 的用户组、进程组、当前的工作目录、执行环境等。 但是,子进程拥有自己的PID、子进程的信号处理函 数也会按照缺省方式初始化、子进程不会继承父进程 的定时器,子进程的信号量也会被初始化。n fork函数返回一个整型的PID,父进程得到的是子进程的 PID,子进程得到的是0。由此可判断当前进程是父进程 还是子进程。pid = fork();pid = fork(); if (pid = 0) /* 子进程 */ else /* 父进程 */ 堆栈代码fork()返回之前pid赋值进入pid=fork();语句之前堆栈代码多进程并发服务器模板pid_t

5、 pid; int listenfd, connfd; listenfd = socket(); bind listen for (;) connfd = accept(listenfd, ); if (pid = fork() = 0) close(listenfd); /* serve the client */ close(connfd); return 0; close(connfd); n 父进程为什么要关闭connfd?子进程为什么要关闭 listenfd? 父子进程共享打开的文件,因此父子进程都可以对已 打开的文件进行操作。如果父进程不关闭connfd,会 产生什么后果?如果子进

6、程不关闭listenfd,会产生 什么后果? 父进程关闭connfd,会不会引起四分节的TCP断连过 程?不会,因为引用计数的存在。如何了解文件的引 用计数?inotify(Linux)/kqueue(FreeBSD、Mac osx)套接口在父子进程的变化ServerClientconnect()listenfdConnection requestServerClientconnect()listenfdStatus of client-server after return from acceptconnfdconnectionserver(parent)clientconnect()lis

7、tenfdconnfdconnectionServer(child)listenfdconnfdfork()Status of client-server after fork returnsserver(parent)Clientconnect()listenfdStatus of client-server after parent and child close appropriate socketsconnectionServer(child)connfd3. 第1个版本多进程并发服务器int main(int argc, char *argv) try Address4 addr;

8、TcpSocket sock, sock1; char bufBUFFER_SIZE; size_t ret;addr.hports(LISTEN_PORT); addr.setAny();sock.serve(addr);while (true) sock.accept(sock1);if (Process:fork() = 0) sock.close(); while(true) if (ret = sock1.read(buf, BUFFER_SIZE) = 0) return 0; ret = sock1.write(buf, ret); sock1.close(); catch (E

9、xception RETURN:=0, 表示正确;-1, 出错 n sigaction结构 struct sigaction union _sighandler_t _sa_handler;void (*_sa_sigaction)(int, struct siginfo *, void *); _u; sigset_t sa_mask; unsigned long sa_flags; void (*sa_restorer)(void); ;n 安装函数 void Signal:installSignalHandler(int num, SigFunc func, struct sigacti

10、on sigemptyset( act.sa_flags = 0; if (num = SIGALRM) act.sa_flags |= SA_RESTART; if (sigaction(num, wait与waitpid函数n wait函数 #include pid_t wait(int *status); RETURN: 成功,终止的子进程ID;出错,-1 n wait函数的问题 同时发生的同类信号只触发一次,wait函数只响应触 发的信号,有可能丢失信号n waitpid函数 pid_t waitpid(pid_t pid, int *status, int options); 当op

11、tions设置为WNOHANG时,如果不指定第1个参数 pid(-1),则会检查是否还有子进程已经终止,从 而干净地处理SIGCHLD信号static void handleSigChld(int num) pid_t pid; int stat;do pid = waitpid(-1, while (pid 0); 信号对阻塞系统调用的影响n 慢系统调用,有可能永远被阻塞的系统调用 read、accept n 阻塞的系统调用除了满足条件从阻塞状态退出外,信号会引起进程 从阻塞态退出。如果由于信号使得系统调用被中断,会返回一个错 误信息EAGAIN。此时,我们需要检查从阻塞态退出的错误值err

12、no RETRY: if (ret = :read(fd_, buf, count) = -1) if (errno = EAGAIN) goto RETRY; else throw EXCEPTION(); 5. 第2版多进程服务器int Process:main(int argc, char *argv) try Address4 addr; TcpSocket sock, sock1; char bufBUFFER_SIZE; size_t ret;pushSignalHandler(SIGCHLD, addr.hports(LISTEN_PORT); addr.setAny();soc

13、k.serve(addr);while (true) sock.accept(sock1);if (fork() = 0) sock.close(); while(true) if (ret = sock1.read(buf, BUFFER_SIZE) = 0) return 0;ret = sock1.write(buf, ret); sock1.close(); catch (Exception return 0; 6. 测试用例n 回归测试 测试单客户是否能正确响应 n 多用户测试 测试在多个客户端同时连入的情况下,是否能够同时 获得服务 n 压力测试 使用单个客户端对服务器做压力测试,

14、测试的目的是 为了了解服务器的latency 小文件的传输时间 大文件的传输时间 使用多个客户端对服务器做压力测试,测试系统的吞 吐量 总的吞吐量测试场测试场 景: n 构造一个空文件,采用一个客户户端测测量传输时间传输时间 n 下载载一个大尺寸文件,例如Ubuntu.iso。采用一个客户户 端测测量传输时间传输时间 ,记录传输时间记录传输时间 ,计计算bps n 同时时启动动多个客户户端,传输传输 ubuntu.iso文件,分别记别记 录录每个客户户端的传输时间传输时间 ,计计算bps;然后相加,得到 总总的吞吐量服务器类型Latency(us) Throughput( bps) 迭代式服务

15、器多进程并发服 务器n 边界条件测试 超时 未知位置的主机 主机断网 主机崩溃 RST 端口未打开 不存在连接 连接已关闭 服务关闭 主机关机vmware上的测试测试 手段n 断网 单击单击 ,选择选择 disconnect n 主机崩溃溃 单击单击 pause按钮钮 n 不存在连接 断开网络络,重启 n 连接已关闭(SIGPIPE) kill服务务器,测试测试 客户户端 n 主机关机 sudo halt作业n 使用多进程方式编写echo服务器,并构造测试环境进行 如下测试 回归测试 测试单客户是否能正确响应 多用户测试 测试在多个客户端同时连入的情况下,是否能够同时获得服 务 压力测试 使用单个客户端对服务器做压力测试 l小文件的传输时间 l大文件的传输时间 使用多个客户端对服务器做压力测试 l总的吞吐量 边界条件测试 超时 l未知位置的主机 l主机断网 l主机崩溃 RST l端口未打开 l不存在连接 l连接已关闭(SIGPIPE) l服务关闭 l主机关机思考题n 编制C+代码,封装信号、进程、文件操作 n 阅读Unix环境高级编程第2版,第7/8/9/10章,复习 进程、信号的相关知识 n 分析Linux源码中signal的实现机制 n 编制程序检验wait函数的问题

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号