杂记12/17——讨论关于服务器实现并发的方式

以下为本人的学习记录,写这些文章目的为做笔记,加深记忆,并未整理订正为专业教学交流内容,所以结构有些混乱,思路比较跳跃,内容也都是自己的理解,不一定正确。若你不经意间发现了这篇文章,如果您有耐心的话,可以给我一些建议或者指出文章的问题(无论是哪个方面)。

感谢!!

这几天来重心一直放在网络编程上,对这一系列的知识点都太陌生了,每当学习新内容时,便会牵扯出更多的新内容,我只能东添西补,一会学这,一会学那。连续这样几天后,总算是摸清楚了一些套路。

对于程序员而言,网络编程,实际上就是利用操作系统给的API,在应用层进行编程,让后API将指令传给操作系统,让其进行运输层,网络层,物理层的打包,最终传输到目的地。

首先,我们的程序可能在不同的系统上运行,例如:

服务器端一般在Linux系统上运行,客户端在其他系统上运行,目前我的首要任务是Linux下服务器的搭建。

有如下一些概念需要理清楚:

socket套接字,当我们初始化一个套接字后,能得到一个文件描述符fd,通过管理文件描述符来管理这个抽象的socket,我们能对socket做这些操作:bind将socket绑定到一个端口上,sockaddr为包含ip和端口信息的一种数据结构,listen利用socket监听绑定的端口,accept接受监听到达请求信息并得到对方的信息,还有connect连接,读写收发,close关闭socket等。有了这些函数,我们便能实现最基础的通信。

但服务器端一个端口应当能接受多个客户端,为了达到这个目的,我们或许想出这种方法

方法1:排队依次处理

在main函数中,不断的循环调用accept函数接受客户端的请求,但这种方式有问题,就是客户端必须排队,等到前面的客户端working结束后才能连接。
 

while(1)

{

int rfd=accept();

working(rfd);

}

举个例子,普通打印店:

只有一台打印机,要想打印则必须排队,流程如下

1、去打印店,然后排上队。

去打印店申请打印相当于客户端发起connect请求,排上队相当于进入了监听端口的队列中
2、轮到你时,打印店老板同意让你打印,并让你使用打印机。

打印店老板同意相当于服务器端accept你的请求了

让你使用打印机,相当于开始处理你的需求。

3、你取走文档,打印机空闲,等待下一个用户。

这种方式,每个人都需要等待前面的人打印完成之后才能使用打印机

不符合服务器支持多个用户同时使用的需求。
 

方法2:多线程处理

多线程处理,在main函数中循环accept,收到连接请求后,便创建一个新线程,把用于通信的文件描述符,和处理这个通信的工作函数传进去,在新的线程中处理客户端的需求。

while(1)

{

int rfd=accept();

创建线程(rfd,工作函数);

}

依然以打印店举例

这时打印店,最初只有一台打印机

1、你准备好你的文档,来到打印店;
2、请求打印
3、不需要排队了,只要你发出请求,老板就创建一个打印机给你用
4、你获得打印机使用权了,开始打印;

5、打印完成,老板便将打印机销毁

相当于只要客户端发出connect请求,服务器便accept,并为客户端创建一个线程供其使用,使用完毕之后再将线程销毁。

但这样有个问题,需要频繁的创建销毁线程,消耗很多资源。

于是针对这个方案进行优化:

方法2升级版:线程池处理

在一开始就创建一个线程池,在里面放入适量的线程,每当有客户端请求时,我便把线程分给他用。若客户端太多,导致线程池不够用了,便再创建一些线程添加到线程池中,用完之后再销毁。这样便能减少创建线程和销毁线程的开销。

注意:线程池中线程的创建和销毁是一对应的算法控制的,保证线程够用,且节约资源

	while (1)
	{
		struct myip* pinfo = new myip();
		pinfo->fd = accept(lfd, (struct sockaddr*)&pinfo->addr, (socklen_t*)&clilen);
		if (pinfo->fd == -1)
		{
			perror("accept");
			continue;
		}
		add_task(pool,request_handler , pinfo);
	}

这时打印店,最初便有多台打印机

1、你准备好你的文档,来到打印店;
2、请求打印
3、不需要排队了,只要你发出请求,老板就分配一台打印机给你用,如果没有空闲的打印机,就创建一个打印机加入到店铺中,给你使用
4、你获得打印机使用权了,开始打印;

5、打印完成,打印机回归空闲

方法3:Linux的epoll模型

此时打印店只有一台打印机,你只要排上队,老板便会管理你的请求

(相当于connect被accept,那你的业务就归epoll管了)
1、告诉老板说,我先排队在这位置,轮到我了通知一声(假定你来回路上不耗时);
2、你先去忙你的事情去了;
3、轮到你了,店小二通知你(假定你来回路上不耗时);
4、你获得打印机使用权了,开始打印;
5、打印完了拿走。

你会发现,你节省了排队的时间,等到你能获得打印机资源的时候,告诉你来处理。但是这里,就浪费了一点时间,就是你自己打印。这就是epoll的同步非阻塞。

方法4:windows的IOCP模型

1、你准备好你的文档,来到打印店;
2、告诉店小二说,我先排队,轮到我了帮打印下,好了通知我(也假定你来回路上不耗时);
3、你先去忙你的事情去了;
4、轮到你的文档了,店小二直接帮你打印好了,通知你;
5、你来了,直接取走文档。

  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值