Unix C语言编写基于进程的小型并发服务器

并发介绍

若是逻辑控制流在时间上是重叠的,那么它们就是并发的,能够出如今计算机系统的不一样层面上,硬件异常处理程序、进程和Unix信号处理程序都是并发的。并发能够看做是操做系统内核用来运行多个应用程序的机制,可是并发不局限于内核。它也能够在应用程序中扮演角色。并发的主要做用有:访问慢速IO设备;与人交互的程序;经过推迟工做以下降延迟;服务多个网络客户端的请求。并发一般能够有三种,基于进程、基于IO多路复用、基于线程。 服务器

基于进程的并发

进程是一个程序运行的实例。每个进程都有本身独立的地址空间,通常状况下,包括文本区域、数据区域和堆栈。文本区域是存储处理器执行的代码;数据区域存储变量和线程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。程序是一个没有生命的实体,只有处理器赋予程序生命,而后由操做系统去执行它,它才能称做一个实体,称为进程。 网络

一个并发服务器的天然构造方法是,在父进程中接受客户端的链接请求,而后建立一个子进程来为每一个新客户端提供服务。在链接接受请求以后,服务器派生一个子进程,这个子进程获取服务器描述符表的完整拷贝,子进程关闭它的拷贝的监听描述符,而父进程关闭它的已链接描述符,不然,将永远不会释放已链接描述符的文件表条目,并且由此引起的存储器泄露将最终消耗尽可用的服务器,使系统崩溃。 并发

对于父、子进程间共享状态信息,进程有一个很是清晰的模型:共享文件表,可是不共享用户地址空间。进程有独立的地址空间既是优势,也是缺点,这样一来,一个进程不可能不当心覆盖另外一个进程的虚拟存储器;另外一方面,独立的地址空间使得进程之间共享信息变得更加困难。另外,基于进程的设计另外一个缺点是,每每运行比较慢,由于进程控制和IPC开销比较高。 app

Unix C实现基于进程的小型并发服务器

本程序在Unix 环境下用C语言开发的,而且调用了csapp.h的现成头文件。 函数

//本程序是一个基于多进程的并发echo服务器,父进程派生一个子进程来处理每一个新的链接请求
#include "csapp.h"
//echo程序,用于向客户端发送响应主体
void echo(int connfd)
{
	int n;
	char buf[MAXLINE];
	rio_t rio;
	
	rio_readinitb(&rio,connfd);
	//带缓冲的读取函数
	while((n=rio_readlineb(&rio,buf,MAXLINE))>0) {
		//向链接符写入内容
		printf("server received %d bytes \n",n);
		rio_writen(connfd,buf,n);
	}
}

//信号处理函数,用于处理僵死进程,即回收已经终止的进程给系统带来的资源占用
void sigchld_handler(int sig)
{
	//-1表明回收父进程的子进程组,因为unix信号是不排队的,所以必须准备好回收多个僵死子进程的准备
	while(waitpid(-1,0,WNOHANG)>0)
		;
	return;
}

int main(int argc,char **argv)
{
	int listenfd,connfd,port;
	socklen_t clientlen=sizeof(struct sockaddr_in);
	struct sockaddr_in clientaddr;
	
	if(argc!=2) {
		fprintf(stderr,"usage :%s <port>\n",argv[0]);
		exit(0);
	}
	//将字符串转化为整型,端口号
	port=atoi(argv[1]);
	//启动信号处理函数监听器
	signal(SIGCHLD,sigchld_handler);
	//启动服务器监听描述符
	listenfd=open_listenfd(port);
	while(1) {
		//已链接描述符,接受链接
		connfd=accept(listenfd,(SA *)&clientaddr,&clientlen);
		//开辟子进程,用于处理链接请求
		if(fork()==0) {
			//因为子进程共享父进程的全部资源,所以先关闭监听描述符,再调用请求体命令,而后关闭已链接描述符,而且正常终止此进程
			close(listenfd);
			echo(connfd);
			close(connfd);
			exit(0);
		}
		//关闭父进程的已链接描述符
		close(connfd);
	}
}
使用telnet来测试程序:

zzw@zzw-ThinkPad-Edge-E430c:~$ telnet localhost 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hello
hello



root@zzw-ThinkPad-Edge-E430c:/home/zzw/doc_main/CProgram/Concurrency# ./echoserverp.o 8080
server received 7 bytes
相关文章
相关标签/搜索