《并发服务器》PPT课件.ppt
《《并发服务器》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《并发服务器》PPT课件.ppt(58页珍藏版)》请在三一办公上搜索。
1、第五章 并发服务器,并发服务器基础多进程服务器多线程服务器I/O多路复用服务器非阻塞socket信号驱动I/O,5.1并发服务器基础(1),理解多客户问题,连接到一个服务器上的多客户示意图服务器以并发方式为多客户提供服务,5.1并发服务器基础(2),服务器分类按连接类型面向连接的服务器 采用TCP协议,可靠。不足之处是:每个连接需要相应的套接字,服务器要管理这些套接字,占用系统资源;连接需要建立和关闭过程,影响传输效率和响应时间,增加服务器负担。无连接的服务器 采用uCP协议,但效率高,占用较少系统资源,服务器不必管理连接套接字。缺点:不可靠,需要程序中实现相应机制。按处理方式重复性服务器:每
2、次只处理一个客户请求,当上一个客户请求处理完成后,才处理下一个请求,简单,效率低。并发服务器:每次可处理多个客户请求,复杂,效率高。,5.1并发服务器基础(3),重复性服务器实现:使用setsockopt()的SO_REUSEADDR选项实现典型代码:int opt,len;len=sizeof(opt)opt=SO_REUSEADDR;setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,实例:源程序名:itrclient.cpp和itrserver.cpp,5.1并发服务器基础(4),功能:服务器等候客户连接,连接显示信息,并循环接收来自客户的信息;收到后显示之,反转
3、后发回客户,直到某客户端输入“bye”关闭连接,就能等待下一客户请求。客户首先与服务器连接,接收键盘输入字符串,发给服务器,接收服务器发回信息并显示,循环,直到bye,关闭连接。运行程序:服务器:%itrserver received client message:1234 客户1:%itrclient connected to server.输入:1234 输出:4321(可以反复输入,均得到反序字符串,直到“bye”为止)思考:客户2、客户3同时运行该程序,结果如何?,5.1并发服务器基础(5),并发服务器与并发技术 进程 进程是程序的一次运行。多个进程可以执行相同的代码(如父子进程),支
4、持并发;单CPU采用分时系统使多个进程同时执行。通过主进程和子进程实现并发,主进程只接收客户请求,子进程只与客户通信。线程 与进程类似,也支持并发。同一进程中的线程共享相同的全程变量和系统分配给该进程的资源,线程间切换更快。进程是最小的资源分配单位,而线程是最小的调度单位。I/O多路复用 系统提供select()函数,在多个描述符中选择被击活的描述符进行操作。如一个服务器同时与多个客户端连接,就有多个TCP套接字描述符,采用时分多路复用技术实现进程或线程的并发处理。,5.1并发服务器基础(6),三种并发服务器算法(1)并发无连接服务器算法 无连接服务,不需要等待每个已连接上的数据,不必采用并发
5、技术也能有效处理多个用户,用多进程/线程需处理大量系统开销,因此无连接服务一般不采用并发技术。(2)并发面向连接服务器算法 通过主进程/线程和子进程/线程实现并发,主进程只接收客户请求,子进程只与客户通信。(3)单进程/线程的并发服务器算法 进程/线程需要较多的系统开销,采用I/O多路复用实现处理多个客户连接,不必产生多个进程/线程。,5.2多进程服务器(1),服务器(父进程),服务器(子进程),listenfdconnfd,connect()函数,客户,连接建立,listenfdconnfd,fork()函数,listenfdconnfd,connect()函数,客户,连接建立,listen
6、fdconnfd,服务器(父进程),服务器(子进程),(a)调用accept()前,(b)调用accept()后,(c)调用fork()后,(d),主服务器进程和子服务器进程实现并发,连接请求,父进程关闭连接套接字子进程关闭侦听套接字,5.2多进程服务器(2),进程概念进程是程序在一个数据集上以并发方式运行的一次过程。进程是程序的动态执行。有生存期。由程序、数据、进程控制块构成。一个进程可包括多个程序,一个程序也可对应多个进程。每个进程有唯一的进程标识符pid。用ps命令看当前系统运行的进程。,5.2多进程服务器(3),系统调用创建进程fork()原型:#include#include pid
7、_t fork(void);功能:创建一个新进程,父子进程共享代码段。返回值:子进程中为0,父进程中为子进程ID,出错为-1。注:用getpid()可以获得当前进程标识符,用getppid()可以获得父进程标识符;通过分支语句控制父子进程执行不同代码(如C/S模式中)。典型代码:pid_t pid;if(pid=fork()0)/*parent process*/else if(pid=0)/*child process*/;exit(0);else cout“fork error!n”;exit(0);,系统中已经有太多的进程或某用户的进程总数超过了系统限制,5.2多进程服务器(4),例1:
8、利用fork()系统调用创建子进程pp1.cpp例2:父子进程享用共同的代码pp2.cpp说明:调用fork()后,父进程/子进程执行顺序不确定程序pp1运行结果 程序pp2运行结果,Just 1 process now.Calling fork()Im the child.Program end.Im the parent.Program end.,pid0=294i=0 j=0 pid=297 ppid=295(4)i=0 j=297 pid=295 ppid=294(2)i=295 j=296 pid=294 ppid=197(1)i=295 j=0 pid=296 ppid=294(3
9、),i=fork(),j=fork(),j=fork(),5.2多进程服务器(5),终止进程exit()、wait()和waitpid1.exit()原型:#include void exit(int status);功能:终止进程,常用于关闭子进程打开的描述符,并返回状态,父进程用wait()、waitpid()获得该状态。返回值:无注:子进程中使用exit()不能完全释放子进程所占用的资源,进程控制块PCB中还保留它的信息,子进程变为“僵尸”进程,ps能看到这样的进程,直到父进程调用wait()后完全释放子进程资源。,5.2多进程服务器(6),父进程可能先于子进程终止,子进程也可能先于父进
10、程终止。2.wait()原型:#include#include pid_t wait(int*stat_loc);功能:在有子进程终止时,系统使用中断信号SIGCHLD通知父进程有子进程终止,此时才能调用wait()。wait()允许父进程取得子进程的状态信息,并挂起,等待子进程终止。返回值:正常,返回子进程进程号,否则-1;同时stat_loc返回子进程返值。典型代码:pid_t pid;int child_status;if(pid=fork()0)/*parent process*/;wait(,5.2多进程服务器(7),原型:#include#include pid_t waitpid
11、(pid_t pid,int*stat_loc,int options);功能:允许父进程取得指定子进程的状态信息,其中:pid是所等待的子进程号,-1时表示第一个子进程;options表示等待的方式,如WNOHANG表示无子进程结束时返回;当pid=-1,options=0时,等价于wait()。返回值:正常,返回子进程号,否则-1;stat_loc返回子进程返值注:若有若干客户同时关闭连接,这些服务进程的父进程同时收到若干SIGCHLD中断信号,由于系统对中断信号无队列设置,导致某些中断信号被丢弃,仍产生“僵尸”进程。waitpid()可以控制无子进程结束时返回。典型代码:clear_ch
12、ild(int signo)int stat,pid;while(pid=waitpid(-1,5.2多进程服务器(8),多进程并发服务器方法用前面所学方法在服务器和客户端建立连接。服务器调用fork()产生子进程。若子进程,关闭监听套接字(保留连接套接字),处理客户请求,最后关闭连接套接字,用exit()退出进程。若父进程,关闭连接套接字(保留监听套接字,套接字描述符的引用计数减1),等待另一客户的连接。,5.2多进程服务器(9),典型代码#include#include#include#include main();listenfd=socket();bind(listenfd,);lis
13、ten(listenfd,);while(1)connfd=accept();if(pid=fork()0)/*parent process*/;close(connfd);continue;else if(pid=0)/*child process*/;close(listenfd);exit(0);else cout“fork errorn”;exit(0);,5.2多进程服务器(10),实例1源程序名:procserver.c和procclient.c功能描述:服务器等候客户连接请求,连接成功后显示客户地址,接收客户名字并显示,循环接收客户字符串并显示,反序处理后发回客户端,服务器可同时
14、处理多客户请求。而客户端先与服务器连接,接收键盘输入的客户名字发给服务器,循环接收用户输入的字符串发给服务器,接收服务器发回的信息并显示,直到D客户关闭连接并退出。运行程序:服务器:$procserver You got a connection from 127.0.0.1.clients name is client1.Received client(client1)message:1234 You got a connection from 127.0.0.1.clients name is client2.Received client(client2)message:abcd,5.2
15、多进程服务器(11),客户1:$procclient Connected to server.Input name:client1 Input string to server:1234 Server Message:4321客户2:$procclient Connected to server.Input name:client2 Input string to server:abcd Server Message:dcba,5.2多进程服务器(12),实例2源程序名:multi.h mulprosrv.cpp mulprocli.cpp功能描述:服务器等候客户连接请求,连接成功后显示客户地
16、址和端口号,循环接收客户的两个整数,相加后发回客户端。服务器可同时处理多客户请求。客户端首先与服务器连接,循环接收用户输入的两个整数发给服务器,接收服务器发回的两数和的信息并显示,询问是否继续(1或0),0返回。运行程序:服务器:$./mulprosrv one client is request service from 127.0.0.1 at PORT 32769(客户1)in process 1231:12+23=35 in process 1231:6+8=14 one client is request service from 202.113.29.19 at PORT 3277
17、0(客户2)in process 2050:2+3=5 client 127.0.0.1 closed child process 1231 cleaned return 0,5.2多进程服务器(13),客户1:$./enter an interger:12 enter another interger:23 12+23=35 would you like to continue(1:continue,0:end):1 enter an interger:6 enter another interger:8 6+8=14 would you like to continue(1:continu
18、e,0:end):0客户2:$./.,5.3多线程服务器(1),线程基础 线程能提高代码响应和性能,线程由系统内核按时间片进行管理,在单处理器系统中,系统内核使用时间分片模拟线程的并发执行,在多处理器系统中,如同多个进程,线程也可以并发执行。同一进程中的线程共享如下内容:全局变量数据虚拟内存打开的文件描述符当前工作目录用户及用户组ID每个线程具有独立的:线程IDerrno变量优先级,5.3多线程服务器(2),POSIX的多线程库1.pthread_create()原型:#include int pthread_create(pthread_t*thread,const pthread_attr
19、_t*attr,void*(*start_func)(void*),void*arg);功能:程序运行时系统产生主线程,该函数产生其它线程,其中:thread:指向线程ID的指针,pthread_t就是unsigned int。attr:指向线程属性的指针,NULL为默认值。start_func:指向线程执行的函数(通用函数指针)。arg:为函数start_func传递参数,若传递多个参数,须封装在一个结构中。返回值:成功返回0,否则返回非零的错误代码。注:fork()创建的子进程与其父进程使用同一个执行点,而pthread_create()中的参数start_func指明新线程要执行的函数,
20、5.3多线程服务器(3),典型代码:#include pthread_t thread;struct ARG int fd;struct sockaddr_in addr;arg;void*start_routine(void*arg);void main()if(pthread_create(/pthread_create()返回非零,表明创建线程失败,5.3多线程服务器(4),2.pthread_exit()原型:#include void pthread_exit(void*value_ptr);功能:终止当前线程,若value_ptr非空则指向线程退出状态。一般用法取NULL。返回值:
21、无,若在线程中调用exit(),将终止该进程所有线程.典型代码:(常用在线程执行的函数中)void*start_routine(void*arg)pthread_exit(NULL);,5.3多线程服务器(5),多线程并发服务器方法用前面所学方法在服务器和客户端建立连接服务器调用pthread_create()产生新线程若主线程,等待另一客户的连接请求若新线程,处理客户请求给新线程传递参数普通方法:使用公共变量传参通过分配arg的空间传递参数注意编译时要和线程库libpthread.a或libpthread.so相连接,如:g+thrserver.cpp o thrserver-lpthrea
22、d,静态链接库,动态链接库,5.3多线程服务器(6),1.普通方法 void*start_routine(void*arg);struct ARG int connfd;int other;void main()struct ARG arg;int listenfd,connfd;pthread_t thread;/*connfd=accept()*/arg.connfd=connfd;arg.other=5;if(pthread_create(,void*start_routine(void*arg)struct ARG info;info.connfd=(struct ARG*)arg)-
23、connfd;info.other=(struct ARG*)arg)-other;close(info.connfd);pthread_exit(NULL);说明:变量arg是所有线程共用的,传递的参数为指针,假设新线程A正处理客户A请求,主线程又接受另一客户B的连接,主线程将修改变量arg内容,故只能处理一个客户,无法同时处理多个客户(不安全)。,5.3多线程服务器(7),5.3多线程服务器(8),2.通过动态分配arg空间传递参数 void*start_routine(void*arg);struct ARG int connfd;int other;void main()int lis
24、tenfd,connfd;ARG*arg;pthread_t thread;/*connfd=accept()*/arg=new ARG;arg-connfd=connfd;arg-other=5;if(pthread_create(,void*start_routine(void*arg)ARG info;info.connfd=(ARG*)arg)-connfd;info.other=(ARG*)arg)-other;close(info.connfd);delete arg;pthread_exit(NULL);说明:创建新线程前,为新线程动态分配存储arg的空间,传递参数给新线程,新线
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 并发服务器 并发 服务器 PPT 课件

链接地址:https://www.31ppt.com/p-5634089.html