精华内容
下载资源
问答
  • IO 多路复用是什么意思? 转自:https://www.zhihu.com/question/32163005 1 IO 多路复用是什么意思? - 罗志宇的回答 - 知乎 https://www.zhihu.com/question/32163005/answer/55772739 这个还是很好说清楚的。 ...

    IO 多路复用是什么意思?

    转自:https://www.zhihu.com/question/32163005

    1 IO 多路复用是什么意思? - 罗志宇的回答 - 知乎 https://www.zhihu.com/question/32163005/answer/55772739

    这个还是很好说清楚的。

    假设你是一个机场的空管, 你需要管理到你机场的所有的航线, 包括进港,出港, 有些航班需要放到停机坪等待,有些航班需要去登机口接乘客。

    你会怎么做?

    最简单的做法,就是你去招一大批空管员,然后每人盯一架飞机, 从进港,接客,排位,出港,航线监控,直至交接给下一个空港,全程监控。

    那么问题就来了:

    很快你就发现空管塔里面聚集起来一大票的空管员,交通稍微繁忙一点,新的空管员就已经挤不进来了。
    空管员之间需要协调,屋子里面就1, 2个人的时候还好,几十号人以后 ,基本上就成菜市场了。
    空管员经常需要更新一些公用的东西,比如起飞显示屏,比如下一个小时后的出港排期,最后你会很惊奇的发现,每个人的时间最后都花在了抢这些资源上。

    现实上我们的空管同时管几十架飞机稀松平常的事情, 他们怎么做的呢?
    他们用这个东西

    这个东西叫flight progress strip. 每一个块代表一个航班,不同的槽代表不同的状态,然后一个空管员可以管理一组这样的块(一组航班),而他的工作,就是在航班信息有新的更新的时候,把对应的块放到不同的槽子里面。

    这个东西现在还没有淘汰哦,只是变成电子的了而已。。

    是不是觉得一下子效率高了很多,一个空管塔里可以调度的航线可以是前一种方法的几倍到几十倍。

    如果你把每一个航线当成一个Sock(I/O 流), 空管当成你的服务端Sock管理代码的话.

    第一种方法就是最传统的多进程并发模型 (每进来一个新的I/O流会分配一个新的进程管理。)
    第二种方法就是I/O多路复用 (单个线程,通过记录跟踪每个I/O流(sock)的状态,来同时管理多个I/O流 。)

    其实“I/O多路复用”这个坑爹翻译可能是这个概念在中文里面如此难理解的原因。所谓的I/O多路复用在英文中其实叫 I/O multiplexing. 如果你搜索multiplexing啥意思,基本上都会出这个图:

    于是大部分人都直接联想到"一根网线,多个sock复用" 这个概念,包括上面的几个回答, 其实不管你用多进程还是I/O多路复用, 网线都只有一根好伐。多个Sock复用一根网线这个功能是在内核+驱动层实现的。

    重要的事情再说一遍: I/O multiplexing 这里面的 multiplexing 指的其实是在单个线程通过记录跟踪每一个Sock(I/O流)的状态(对应空管塔里面的Fight progress strip槽)来同时管理多个I/O流. 发明它的原因,是尽量多的提高服务器的吞吐能力。

    是不是听起来好拗口,看个图就懂了.

    在同一个线程里面, 通过拨开关的方式,来同时传输多个I/O流, (学过EE的人现在可以站出来义正严辞说这个叫“时分复用”了)。

    什么,你还没有搞懂“一个请求到来了,nginx使用epoll接收请求的过程是怎样的”, 多看看这个图就了解了。提醒下,ngnix会有很多链接进来, epoll会把他们都监视起来,然后像拨开关一样,谁有数据就拨向谁,然后调用相应的代码处理。

    ------------------------------------------
    了解这个基本的概念以后,其他的就很好解释了。

    select, poll, epoll 都是I/O多路复用的具体的实现,之所以有这三个鬼存在,其实是他们出现是有先后顺序的。

    I/O多路复用这个概念被提出来以后, select是第一个实现 (1983 左右在BSD里面实现的)。

    select 被实现以后,很快就暴露出了很多问题。

    select 会修改传入的参数数组,这个对于一个需要调用很多次的函数,是非常不友好的。
    select 如果任何一个sock(I/O stream)出现了数据,select 仅仅会返回,但是并不会告诉你是那个sock上有数据,于是你只能自己一个一个的找,10几个sock可能还好,要是几万的sock每次都找一遍,这个无谓的开销就颇有海天盛筵的豪气了。
    select 只能监视1024个链接, 这个跟草榴没啥关系哦,linux 定义在头文件中的,参见FD_SETSIZE。
    select 不是线程安全的,如果你把一个sock加入到select, 然后突然另外一个线程发现,尼玛,这个sock不用,要收回。对不起,这个select 不支持的,如果你丧心病狂的竟然关掉这个sock, select的标准行为是。。呃。。不可预测的, 这个可是写在文档中的哦.
    “If a file descriptor being monitored by select() is closed in another thread, the result is unspecified”
    霸不霸气

    于是14年以后(1997年)一帮人又实现了poll, poll 修复了select的很多问题,比如

    poll 去掉了1024个链接的限制,于是要多少链接呢, 主人你开心就好。
    poll 从设计上来说,不再修改传入数组,不过这个要看你的平台了,所以行走江湖,还是小心为妙。
    其实拖14年那么久也不是效率问题, 而是那个时代的硬件实在太弱,一台服务器处理1千多个链接简直就是神一样的存在了,select很长段时间已经满足需求。

    但是poll仍然不是线程安全的, 这就意味着,不管服务器有多强悍,你也只能在一个线程里面处理一组I/O流。你当然可以那多进程来配合了,不过然后你就有了多进程的各种问题。

    于是5年以后, 在2002, 大神 Davide Libenzi 实现了epoll.

    epoll 可以说是I/O 多路复用最新的一个实现,epoll 修复了poll 和select绝大部分问题, 比如:

    epoll 现在是线程安全的。
    epoll 现在不仅告诉你sock组里面数据,还会告诉你具体哪个sock有数据,你不用自己去找了。

    epoll 当年的patch,现在还在,下面链接可以看得到:
    /dev/epoll Home Page

    贴一张霸气的图,看看当年神一样的性能(测试代码都是死链了, 如果有人可以刨坟找出来,可以研究下细节怎么测的).

    横轴Dead connections 就是链接数的意思,叫这个名字只是它的测试工具叫deadcon. 纵轴是每秒处理请求的数量,你可以看到,epoll每秒处理请求的数量基本不会随着链接变多而下降的。poll 和/dev/poll 就很惨了。

    可是epoll 有个致命的缺点。。只有linux支持。比如BSD上面对应的实现是kqueue。

    其实有些国内知名厂商把epoll从安卓里面裁掉这种脑残的事情我会主动告诉你嘛。什么,你说没人用安卓做服务器,尼玛你是看不起p2p软件了啦。

    而ngnix 的设计原则里面, 它会使用目标平台上面最高效的I/O多路复用模型咯,所以才会有这个设置。一般情况下,如果可能的话,尽量都用epoll/kqueue吧。

    详细的在这里:
    Connection processing methods

    PS: 上面所有这些比较分析,都建立在大并发下面,如果你的并发数太少,用哪个,其实都没有区别。 如果像是在欧朋数据中心里面的转码服务器那种动不动就是几万几十万的并发,不用epoll我可以直接去撞墙了。

    I/O复用是不是用跟各种池一起用的?
    线程池和sock池都和具体实现有关。所以你要告诉我你指的线程池是某个实现呢,还是通常意义上的“线程池”

    通常意义上的线程池只是多线程里面对线程生命周期的一个管理方法而已(不用的线程不是直接结束掉,而是放到池里面复用, 以避免创建/销毁线程的开销),和并发模型没有关系。线程池=空管员宿舍。没有宿舍,空管员都要从家里来上班,有了宿舍,上下班开销变小。但是和空管们工作方式没有关系。

    不过很多很多的文章里面说的线程池其实是和多线程模型一起用的(多进程模型里面把进程换成线程)。这种情况一般是一个线程一个sock.

    如果用I/O复用和线程池,一般是一个线程一组I/O, 然后可能另外还有一堆工作线程处理具体数据。。

    关于socket 一个端口和多个端口通信如何通信?你注意到了accept会返回一个新的socket描述符么。。所以服务端只会监听一个端口,每次来了新的请求,都会创建一个新的sock和客户端通信。

    每个socket就是一个I/O流,不考虑协议的情况下,确实就是两端IP和端口不同(服务器可能有多个IP). 不管这个socket在不在池里面。

    展开全文
  • IO多路复用是什么意思,在实际的应用中是指什么情况? 以及IO多路复用在一些异步web server中的实际应用,就好比nginx是怎样使用epoll来实现异步IO处理的,一个请求到来了,nginx使用epoll接收请求的过程是怎样的.....

    提问一:

    Linux IO多路复用有 epoll, poll, select,知道epoll性能比其他几者要好。也在网上查了一下这几者的区别,表示没有弄明白。

    IO多路复用是什么意思,在实际的应用中是指什么情况?

    以及IO多路复用在一些异步web server中的实际应用,就好比nginx是怎样使用epoll来实现异步IO处理的,一个请求到来了,nginx使用epoll接收请求的过程是怎样的?

    回答1

    作者:罗志宇

    这个还是很好说清楚的。

    假设你是一个机场的空管, 你需要管理到你机场的所有的航线, 包括进港,出港, 有些航班需要放到停机坪等待,有些航班需要去登机口接乘客。

    你会怎么做?

    最简单的做法,就是你去招一大批空管员,然后每人盯一架飞机, 从进港,接客,排位,出港,航线监控,直至交接给下一个空港,全程监控。

    那么问题就来了:

    • 很快你就发现空管塔里面聚集起来一大票的空管员,交通稍微繁忙一点,新的空管员就已经挤不进来了。
    • 空管员之间需要协调,屋子里面就1, 2个人的时候还好,几十号人以后 ,基本上就成菜市场了。
    • 空管员经常需要更新一些公用的东西,比如起飞显示屏,比如下一个小时后的出港排期,最后你会很惊奇的发现,每个人的时间最后都花在了抢这些资源上。

    现实上我们的空管同时管几十架飞机稀松平常的事情, 他们怎么做的呢?

    他们用这个东西

    这个东西叫flight progress strip。 每一个块代表一个航班,不同的槽代表不同的状态,然后一个空管员可以管理一组这样的块(一组航班),而他的工作,就是在航班信息有新的更新的时候,把对应的块放到不同的槽子里面。

    这个东西现在还没有淘汰哦,只是变成电子的了而已。。

    是不是觉得一下子效率高了很多,一个空管塔里可以调度的航线可以是前一种方法的几倍到几十倍。

    如果你把每一个航线当成一个Sock(I/O 流), 空管当成你的服务端Sock管理代码的话。

    • 第一种方法就是最传统的多进程并发模型 (每进来一个新的I/O流会分配一个新的进程管理。)
    • 第二种方法就是I/O多路复用 (单个线程,通过记录跟踪每个I/O流(sock)的状态,来同时管理多个I/O流 。)

    其实“I/O多路复用”这个坑爹翻译可能是这个概念在中文里面如此难理解的原因。所谓的I/O多路复用在英文中其实叫 I/O multiplexing。 如果你搜索multiplexing啥意思,基本上都会出这个图:

    于是大部分人都直接联想到"一根网线,多个sock复用" 这个概念,包括上面的几个回答, 其实不管你用多进程还是I/O多路复用, 网线都只有一根。多个Sock复用一根网线这个功能是在内核+驱动层实现的

    重要的事情再说一遍: I/O multiplexing 这里面的 multiplexing 指的其实是在单个线程通过记录跟踪每一个Sock(I/O流)的状态(对应空管塔里面的Fight progress strip槽)来同时管理多个I/O流。

    发明它的原因,是尽量多的提高服务器的吞吐能力。

    是不是听起来好拗口,看个图就懂了。

    在同一个线程里面, 通过拨开关的方式,来同时传输多个I/O流, (学过EE的人现在可以站出来义正严辞说这个叫“时分复用”了)。

    什么,你还没有搞懂“一个请求到来了,nginx使用epoll接收请求的过程是怎样的”, 多看看这个图就了解了。提醒下,ngnix会有很多链接进来, epoll会把他们都监视起来,然后像拨开关一样,谁有数据就拨向谁,然后调用相应的代码处理。

    ------------------------------------------

    了解这个基本的概念以后,其他的就很好解释了。

    select, poll, epoll 都是I/O多路复用的具体的实现,之所以有这三个鬼存在,其实是他们出现是有先后顺序的。

    I/O多路复用这个概念被提出来以后, select是第一个实现 (1983 左右在BSD里面实现的)。

    select 被实现以后,很快就暴露出了很多问题。

    • select 会修改传入的参数数组,这个对于一个需要调用很多次的函数,是非常不友好的。
    • select 如果任何一个sock(I/O stream)出现了数据,select 仅仅会返回,但是并不会告诉你是那个sock上有数据,于是你只能自己一个一个的找,10几个sock可能还好,要是几万的sock每次都找一遍,这个无谓的开销就颇有海天盛筵的豪气了。
    • select 只能监视1024个链接, 这个跟草榴没啥关系哦,Linux 定义在头文件中的,参见FD_SETSIZE。
    • select 不是线程安全的,如果你把一个sock加入到select, 然后突然另外一个线程发现,尼玛,这个sock不用,要收回。对不起,这个select 不支持的,如果你丧心病狂的竟然关掉这个sock, select的标准行为是。。呃。。不可预测的, 这个可是写在文档中的哦。

    “If a file descriptor being monitored by select() is closed in another thread, the result is unspecified”

    霸不霸气

    于是14年以后(1997年)一帮人又实现了poll, poll 修复了select的很多问题,比如

    • poll 去掉了1024个链接的限制,于是要多少链接呢, 主人你开心就好。
    • poll 从设计上来说,不再修改传入数组,不过这个要看你的平台了,所以行走江湖,还是小心为妙。

    其实拖14年那么久也不是效率问题, 而是那个时代的硬件实在太弱,一台服务器处理1千多个链接简直就是神一样的存在了,select很长段时间已经满足需求。

    但是poll仍然不是线程安全的, 这就意味着,不管服务器有多强悍,你也只能在一个线程里面处理一组I/O流。你当然可以那多进程来配合了,不过然后你就有了多进程的各种问题。

    于是5年以后, 在2002, 大神 Davide Libenzi 实现了epoll。

    epoll 可以说是I/O 多路复用最新的一个实现,epoll 修复了poll 和select绝大部分问题, 比如:

    • epoll 现在是线程安全的。
    • epoll 现在不仅告诉你sock组里面数据,还会告诉你具体哪个sock有数据,你不用自己去找了。

    epoll 当年的patch,现在还在,下面链接可以看得到:

    /dev/epoll Home Page

    贴一张霸气的图,看看当年神一样的性能(测试代码都是死链了, 如果有人可以刨坟找出来,可以研究下细节怎么测的)。

    横轴Dead connections 就是链接数的意思,叫这个名字只是它的测试工具叫deadcon。 纵轴是每秒处理请求的数量,你可以看到,epoll每秒处理请求的数量基本不会随着链接变多而下降的。poll 和/dev/poll 就很惨了。

    可是epoll 有个致命的缺点。。只有linux支持。比如BSD上面对应的实现是kqueue。

    其实有些国内知名厂商把epoll从安卓里面裁掉这种脑残的事情我会主动告诉你嘛。什么,你说没人用安卓做服务器,尼玛你是看不起p2p软件了啦。

    而 ngnix 的设计原则里面, 它会使用目标平台上面最高效的I/O多路复用模型咯,所以才会有这个设置。一般情况下,如果可能的话,尽量都用epoll/kqueue吧。

    详细的在这里:

    Connection processing methods

    PS: 上面所有这些比较分析,都建立在大并发下面,如果你的并发数太少,用哪个,其实都没有区别。 如果像是在欧朋数据中心里面的转码服务器那种动不动就是几万几十万的并发,不用epoll我可以直接去撞墙了

    回答2:

    要弄清问题 先要知道问题的出现原因

    原因:

    由于进程的执行过程是线性的(也就是顺序执行),当我们调用低速系统I/O(read,write,accept等等),进程可能阻塞,此时进程就阻塞在这个调用上,不能执行其他操作。阻塞很正常。 接下来考虑这么一个问题:

    一个服务器进程和一个客户端进程通信,服务器端read(sockfd1,bud,bufsize),此时客户端进程没有发送数据,那么read(阻塞调用)将阻塞直到客户端调用write(sockfd,but,size)发来数据。 在一个客户和服务器通信时这没什么问题,当多个客户与服务器通信时,若服务器阻塞于其中一个客户sockfd1,当另一个客户的数据到达套接字sockfd2时,服务器不能处理,仍然阻塞在read(sockfd1。。。)上;此时问题就出现了,不能及时处理另一个客户的服务,咋么办?I/O多路复用来解决!

    I/O多路复用:

    继续上面的问题,有多个客户连接,sockfd1,sockfd2,sockfd3。。sockfdn同时监听这n个客户,当其中有一个发来消息时就从select的阻塞中返回,然后就调用read读取收到消息的sockfd,然后又循环回select阻塞;

    这样就不会因为阻塞在其中一个上而不能处理另一个客户的消息

     

     

    提问二:I/O复用 与 连接池 的区别

    答主你好,看你的回答好犀利,我菜鸟一个好多概念搞不清楚,想请教你一些。I/O复用是不是用跟各种池一起用的?比如线程池,socket连接池哪些。最困扰的一个问题是一个线程池或socket连接池里面的诸多线程、socket如何利用一个端口与多个端进行通信的呢?还有您能不能能说一下一个socket连接池里面的诸多socket有何不同啊,是不是就只是目的IP和目的端口的区别?万谢!!!

    回答1:

    线程池和socket池都和具体实现有关。所以你要告诉我你指的线程池是某个实现呢,还是通常意义上的“线程池”

    通常意义上的线程池只是多线程里面对线程生命周期的一个管理方法而已(不用的线程不是直接结束掉,而是放到池里面复用,以避免创建/销毁线程的开销),和并发模型没有关系。线程池=空管员宿舍。没有宿舍,空管员都要从家里来上班,有了宿舍,上下班开销变小。但是和空管们工作方式没有关系。

    不过很多很多的文章里面说的线程池其实是和多线程模型一起用的(多进程模型里面把进程换成线程)。这种情况一般是一个线程一个socket。

    如果用I/O复用和线程池,一般是一个线程一组I/O, 然后可能另外还有一堆工作线程处理具体数据。

    关于socket 一个端口和多个端口通信如何通信?你注意到了accept会返回一个新的socket描述符么。所以服务端只会监听一个端口,每次来了新的请求,都会创建一个新的socket和客户端通信。

    每个socket就是一个I/O流,不考虑协议的情况下,确实就是两端IP和端口不同(服务器可能有多个IP)。 不管这个socket在不在池里面。

     

     

     

    摘自:

    http://www.zhihu.com/question/32163005

    展开全文
  • 软件复用是什么意思

    千次阅读 2007-05-31 20:58:00
    软件复用是将已有的软件及其有效成分用于构造新的软件或系统。它不仅是对软件程序的复用,还包括对软件生产过程中其它劳动成果的复用,如项目计划书、可行性报告、需求分析、概要设计、详细设计、编码(源程序)、测试...
    软件复用是将已有的软件及其有效成分用于构造新的软件或系统。它不仅是对软件程序的复用,还包括对软件生产过程中其它劳动成果的复用,如项目计划书、可行性报告、需求分析、概要设计、详细设计、编码(源程序)、测试用例、文档与使用手册等等。因此,软件复用包括软件产品复用和软件过程复用两部分的内容。 
    软件复用不同于软件移植。软件移植是指对软件进行修改和扩充,使之在保留原有功能、适应原有平台的基础上,可以运行于新的软硬件平台。而复用则指在多个系统中,尤其是在新系统中使用已有的软件成分。
    从对复用产品的了解程度和复用方式看,也可分为白盒复用与黑盒复用。黑盒复用指对已有产品或构件不需作任何修改,直接进行复用,这是理想的复用方式。它主要基于二进制代码的复用,包括可执行程序的复用和基于库(包括动态链接库和静态库)的复用。白盒复用指根据用户需求对已有产品进行适应性修改后才可使用。白盒复用一般为源代码一级的复用,以及相应的测试用例、文档等的复用。
    无论白盒复用还是黑盒复用,都需要花费一定的代价熟悉和掌握被复用的软件系统。作为经济上的考虑,要求复用的代价必须大大小于重新开发的代价,否则就不应该考虑。
    软件复用的一个关键因素是抽象。抽象是对软件可复用对象的提炼和概括,即将可复用对象的基本属性和相应的操作,从具体的语言、环境和其他细节中提炼出来。软件的复用性很大程度上取决于对可复用对象的认识深度或者说可复用对象的抽象层次。抽象层次越高、与具体环境和特定细节越无关,则它被未来系统复用的可能性也越大。领域分析则是进行抽象的有力工具。领域分析借助特定领域、特定行业的专业知识与技能,对软件系统对象进行抽象和分类,提炼认知的对象及其相互关系,获得系统整体结构,从而生成可复用的软件构件。
    通过软件复用,在应用系统开发中可以充分地利用已有的开发成果,减少了包括分析、设计、编码、测试等在内的许多重复劳动,从而提高了软件开发的效率,同时,通过复用高质量的已有开发成果,避免了重新开发可能引入的错误,从而提高了软件的质量。
    软件复用有三个基本原则,一是必须有可以复用的对象;二是所复用的对象必须是有用的,三是复用者需要知道如何去使用被复用的对象。软件复用包括两个相关过程:可复用软件(构件)的开发(Development for Reuse)和基于可复用软件(构件)的应用系统构造(集成和组装)(Development with Reuse)。解决好这几个方面的问题才能实现真正成功的软件复用。
    可复用软件(构件)的开发是实现软件复用的基本条件,对象技术的广泛使用,提供了建造和使用构件的概念基础和实用工具,有了可复用软件,基于可复用软件(构件)的应用系统构造(集成和组装)才能得以实现。软件的生产也可以象硬件的生产一样,在设计好框架后通过标准的构件组装而成。一般认为构件是具有一定功能、能够独立工作或同其他构件组合起来协调工作的程序体,一经产生,就与它的具体实现语言无关,可以认为是一段二进制码和数据段,其内部具体实现是无法看到的,可将成熟的构件当作商品出售,在保证开发者的利益同时最大地满足社会需求。采用构件来开发软件可以更有效地重用他人已有的劳动成果。
    在复用软件设计中,如何设计和构造可复用的软件是软件设计者首先要面对的问题。根据面向对象的设计原理,应着眼于以下几个方面:
    (1)封装性
    在软构件的定义中,用户只关心事件的输入输出,对事件内部不必关心,方法和事件是独立于应用的,用户可以在软构件中定义自己的事件,对于内部的复杂性调用这并不知晓,从而提高了隐蔽性。
    (2)重载
    重载就是在同一软件构件中用同一名字来表示不同的方法名。一般有两种实现方法,一是方法参数的个数重载,二是方法参数的类型重载。
    (3)继承
    继承就是高层的类在不同范围的复用。
    (4)聚合
    聚合就是把一个难以复用的大软件分成若干部分构件,使其中的某些构件成为可以复用的构件。
    (5)多态性
    多态性指某方法不仅可以处理有相同结构的对象,也可以处理不同结构的对象。
    中间件及相关软件是商业化的软件复用。仅看程序方面,软件复用后的制品也不只包括中间件软件,还包括软件框架、应用框架、通用业务构件等多种可复用形式。
     
    是指编程吗,说的是以前的程序的整体或部分可以在今后的程序编写中被引用,并实现功能
    软件复用是将已有的软件及其有效成分用于构造新的软件或系统。它不仅是对软件程序的复用,还包括对软件生产过程中其它劳动成果的复用,如项目计划书、可行性报告、需求分析、概要设计、详细设计、编码(源程序)、测试用例、文档与使用手册等等。因此,软件复用包括软件产品复用和软件过程复用两部分的内容。
    软件复用不同于软件移植。软件移植是指对软件进行修改和扩充,使之在保留原有功能、适应原有平台的基础上,可以运行于新的软硬件平台。而复用则指在多个系统中,尤其是在新系统中使用已有的软件成分。
    从对复用产品的了解程度和复用方式看,也可分为白盒复用与黑盒复用。黑盒复用指对已有产品或构件不需作任何修改,直接进行复用,这是理想的复用方式。它主要基于二进制代码的复用,包括可执行程序的复用和基于库(包括动态链接库和静态库)的复用。白盒复用指根据用户需求对已有产品进行适应性修改后才可使用。白盒复用一般为源代码一级的复用,以及相应的测试用例、文档等的复用。
    无论白盒复用还是黑盒复用,都需要花费一定的代价熟悉和掌握被复用的软件系统。作为经济上的考虑,要求复用的代价必须大大小于重新开发的代价,否则就不应该考虑。
    软件复用的一个关键因素是抽象。抽象是对软件可复用对象的提炼和概括,即将可复用对象的基本属性和相应的操作,从具体的语言、环境和其他细节中提炼出来。软件的复用性很大程度上取决于对可复用对象的认识深度或者说可复用对象的抽象层次。抽象层次越高、与具体环境和特定细节越无关,则它被未来系统复用的可能性也越大。领域分析则是进行抽象的有力工具。领域分析借助特定领域、特定行业的专业知识与技能,对软件系统对象进行抽象和分类,提炼认知的对象及其相互关系,获得系统整体结构,从而生成可复用的软件构件。
    通过软件复用,在应用系统开发中可以充分地利用已有的开发成果,减少了包括分析、设计、编码、测试等在内的许多重复劳动,从而提高了软件开发的效率,同时,通过复用高质量的已有开发成果,避免了重新开发可能引入的错误,从而提高了软件的质量。
    软件复用有三个基本原则,一是必须有可以复用的对象;二是所复用的对象必须是有用的,三是复用者需要知道如何去使用被复用的对象。软件复用包括两个相关过程:可复用软件(构件)的开发(Development for Reuse)和基于可复用软件(构件)的应用系统构造(集成和组装)(Development with Reuse)。解决好这几个方面的问题才能实现真正成功的软件复用。
    可复用软件(构件)的开发是实现软件复用的基本条件,对象技术的广泛使用,提供了建造和使用构件的概念基础和实用工具,有了可复用软件,基于可复用软件(构件)的应用系统构造(集成和组装)才能得以实现。软件的生产也可以象硬件的生产一样,在设计好框架后通过标准的构件组装而成。一般认为构件是具有一定功能、能够独立工作或同其他构件组合起来协调工作的程序体,一经产生,就与它的具体实现语言无关,可以认为是一段二进制码和数据段,其内部具体实现是无法看到的,可将成熟的构件当作商品出售,在保证开发者的利益同时最大地满足社会需求。采用构件来开发软件可以更有效地重用他人已有的劳动成果。
    在复用软件设计中,如何设计和构造可复用的软件是软件设计者首先要面对的问题。根据面向对象的设计原理,应着眼于以下几个方面:
    (1)封装性
    在软构件的定义中,用户只关心事件的输入输出,对事件内部不必关心,方法和事件是独立于应用的,用户可以在软构件中定义自己的事件,对于内部的复杂性调用这并不知晓,从而提高了隐蔽性。
    (2)重载
    重载就是在同一软件构件中用同一名字来表示不同的方法名。一般有两种实现方法,一是方法参数的个数重载,二是方法参数的类型重载。
    (3)继承
    继承就是高层的类在不同范围的复用。
    (4)聚合
    聚合就是把一个难以复用的大软件分成若干部分构件,使其中的某些构件成为可以复用的构件。
    (5)多态性
    多态性指某方法不仅可以处理有相同结构的对象,也可以处理不同结构的对象。
    中间件及相关软件是商业化的软件复用。仅看程序方面,软件复用后的制品也不只包括中间件软件,还包括软件框架、应用框架、通用业务构件等多种可复用形式。
    软件复用(SoftWare Reuse)是将已有软件的各种有关知识用于建立新的软件,以缩减软件开发和维护的花费。软件复用是提高软件生产力和质量的一种重要技术。早期的软件复用主要是代码级复用,被复用的知识专指程序,后来扩大到包括领域知识、开发经验、设计决定、体系结构、需求、设计、代码和文档等一切有关方面。
    展开全文
  • 写在前面:本文整理于知乎...假设你一个机场的空管, 你须要管理到你机场的全部的航线。 包含进港,出港, 有些航班须要放到停机坪等待,有些航班须要去登机口接乘客。 你会怎么做? 那么问题就来了: 非常快你...

    写在前面:本文整理于知乎,原文链接为http://www.zhihu.com/question/32163005/answer/55772739,作者:罗志宇
    再次向作者表示感谢~~

    假设你是一个机场的空管, 你须要管理到你机场的全部的航线。 包含进港,出港, 有些航班须要放到停机坪等待,有些航班须要去登机口接乘客。

    你会怎么做?

    那么问题就来了:
    非常快你就发现空管塔里面聚集起来一大票的空管员,交通略微繁忙一点,新的空管员就已经挤不进来了。
    空管员之间须要协调,屋子里面就1, 2个人的时候还好,几十号人以后 。基本上就成菜市场了。


    空管员常常须要更新一些公用的东西。比方起飞显示屏,比方下一个小时后的出港排期。最后你会非常惊奇的发现,每个人的时间最后都花在了抢这些资源上。

    现实上我们的空管同一时候管几十架飞机稀松寻常的事情, 他们怎么做的呢?
    他们用这个东西

       ![这里写图片描写叙述](https://pic2.zhimg.com/583d5ba3cee12e78befa8e2b749f4269_b.jpg)
    

    这个东西叫flight progress strip. 每个块代表一个航班,不同的槽代表不同的状态,然后一个空管员能够管理一组这种块(一组航班),而他的工作。就是在航班信息有新的更新的时候。把相应的块放到不同的槽子里面。

    这个东西如今还没有淘汰哦,仅仅是变成电子的了而已。

    是不是认为一下子效率高了非常多,一个空管塔里能够调度的航线能够是前一种方法的几倍到几十倍。

    假设你把每个航线当成一个Sock(I/O 流), 空管当成你的服务端Sock管理代码的话.

    第一种方法就是最传统的多进程并发模型 (每进来一个新的I/O流会分配一个新的进程管理。)
    另外一种方法就是I/O多路复用 (单个线程,通过记录跟踪每个I/O流(sock)的状态,来同一时候管理多个I/O流 。

    )

    事实上“I/O多路复用”这个坑爹翻译可能是这个概念在中文里面如此难理解的原因。所谓的I/O多路复用在英文中事实上叫 I/O multiplexing. 假设你搜索multiplexing啥意思,基本上都会出这个图:

    这里写图片描写叙述
    于是大部分人都直接联想到”一根网线。多个sock复用” 这个概念,包含上面的几个回答。 事实上无论你用多进程还是I/O多路复用。 网线都仅仅有一根好伐。多个Sock复用一根网线这个功能是在内核+驱动层实现的。

    重要的事情再说一遍: I/O multiplexing 这里面的 multiplexing 指的事实上是在单个线程通过记录跟踪每个Sock(I/O流)的状态(相应空管塔里面的Fight progress strip槽)来同一时候管理多个I/O流. 发明它的原因,是尽量多的提高server的吞吐能力。

    是不是听起来好拗口,看个图就懂了.

    这里写图片描写叙述
    在同一个线程里面, 通过拨开关的方式。来同一时候传输多个I/O流。 (学过EE的人如今能够站出来义正严辞说这个叫“时分复用”了)。

    什么,你还没有搞懂“一个请求到来了,nginx使用epoll接收请求的过程是如何的”。 多看看这个图就了解了。

    提醒下,ngnix会有非常多链接进来, epoll会把他们都监视起来,然后像拨开关一样。谁有数据就拨向谁。然后调用相应的代码处理。

    ------------------------------------------
    了解这个主要的概念以后,其它的就非常好解释了。

    select, poll, epoll 都是I/O多路复用的详细的实现。之所以有这三个鬼存在,事实上是他们出现是有先后顺序的。

    I/O多路复用这个概念被提出来以后。 select是第一个实现 (1983 左右在BSD里面实现的)。

    select 被实现以后,非常快就暴露出了非常多问题。


    select 会改动传入的參数数组。这个对于一个须要调用非常多次的函数,是非常不友好的。
    select 假设不论什么一个sock(I/O stream)出现了数据,select 仅仅会返回,但是并不会告诉你是那个sock上有数据,于是你仅仅能自己一个一个的找,10几个sock可能还好。要是几万的sock每次都找一遍,这个无谓的开销就颇有海天盛筵的豪气了。
    select 仅仅能监视1024个链接。 这个跟草榴没啥关系哦。linux 定义在头文件里的,參见FD_SETSIZE。
    select 不是线程安全的,假设你把一个sock增加到select, 然后突然另外一个线程发现。尼玛。这个sock不用。要收回。对不起。这个select 不支持的,假设你丧心病狂的居然关掉这个sock, select的标准行为是。。

    呃。。不可预測的, 这个但是写在文档中的哦.
    “If a file descriptor being monitored by select() is closed in another thread, the result is unspecified”
    霸不霸气

    于是14年以后(1997年)一帮人又实现了poll, poll 修复了select的非常多问题,比方
    poll 去掉了1024个链接的限制,于是要多少链接呢, 主人你开心就好。
    poll 从设计上来说。不再改动传入数组,只是这个要看你的平台了,所以行走江湖。还是小心为妙。


    事实上拖14年那么久也不是效率问题, 而是那个时代的硬件实在太弱,一台server处理1千多个链接简直就是神一样的存在了,select非常长段时间已经满足需求。

    但是poll仍然不是线程安全的, 这就意味着,无论server有多强悍。你也仅仅能在一个线程里面处理一组I/O流。你当然能够那多进程来配合了,只是然后你就有了多进程的各种问题。

    于是5年以后, 在2002, 大神 Davide Libenzi 实现了epoll.

    epoll 能够说是I/O 多路复用最新的一个实现,epoll 修复了poll 和select绝大部分问题, 比方:
    epoll 如今是线程安全的。


    epoll 如今不仅告诉你sock组里面数据,还会告诉你详细哪个sock有数据,你不用自己去找了。

    epoll 当年的patch,如今还在,以下链接能够看得到:
    /dev/epoll Home Page

    贴一张霸气的图。看看当年神一样的性能(測试代码都是死链了。 假设有人能够刨坟找出来。能够研究下细节怎么測的).

    这里写图片描写叙述
    横轴Dead connections 就是链接数的意思。叫这个名字仅仅是它的測试工具叫deadcon. 纵轴是每秒处理请求的数量,你能够看到。epoll每秒处理请求的数量基本不会随着链接变多而下降的。poll 和/dev/poll 就非常慘了。

    但是epoll 有个致命的缺点。

    。仅仅有linux支持。

    比方BSD上面相应的实现是kqueue。

    事实上有些国内知名厂商把epoll从安卓里面裁掉这种脑残的事情我会主动告诉你嘛。

    什么,你说没人用安卓做server。尼玛你是看不起p2p软件了啦。

    而ngnix 的设计原则里面, 它会使用目标平台上面最高效的I/O多路复用模型咯,所以才会有这个设置。普通情况下,假设可能的话,尽量都用epoll/kqueue吧。

    详细的在这里:
    Connection processing methods

    PS: 上面全部这些比較分析。都建立在大并发以下。假设你的并发数太少,用哪个,事实上都没有差别。

    假设像是在欧朋数据中心里面的转码server那种动不动就是几万几十万的并发,不用epoll我能够直接去撞墙了。

    作者:罗志宇
    链接:http://www.zhihu.com/question/32163005/answer/55772739
    来源:知乎
    著作权归作者全部。商业转载请联系作者获得授权,非商业转载请注明出处。

    转载于:https://www.cnblogs.com/liguangsunls/p/7241415.html

    展开全文
  • 著作权归作者所有。 商业转载请联系作者获得授权,非商业转载请注明出处...假设你一个机场的空管, 你需要管理到你机场的所有的航线, 包括进港,出港, 有些航班需要放到停机坪等待,有些航班需要去登机口接乘客。
  • I/O复用到底是什么意思

    千次阅读 2017-08-18 12:27:01
    问 epoll  网络编程   jql09 2016年03月05日提问 · 2016年03月06日更新 关注 6 关注 收藏 3 收藏,1.4k 浏览 ...UNP网络编程中,有I/O复用
  • 什么是IO多路复用

    2021-01-06 17:21:31
    先百度或者知乎,找到这篇文章 [1]IO 多路复用是什么意思? 文中提到:   第一种好理解,就是来一个请求,fork一个进程,第二种提到I/O多路复用使用单个线程实现的,作者肯定没有写错,因为后面的文章也都是...
  • STM32中功能复用重映射是什么意思

    千次阅读 2016-10-19 16:01:31
    就是IO口可以有多种用途,比如可以作为普通的输入输出口使用,也可以作为PWM通道使用,还有DAC通道等, 但需要相应的配置。I/O口不可以同时进行这三个功能的使用,只能配置为什么功能使用相应的功能。
  • 7、合成复用原则(Composite Reuse Principle) 合成复用原则就是在一个新的对象里通过关联关系(组合关系、聚合关系)来使用一些已有的对象,使之成为新对象的一部分;新对象通过委派调用已有对象的方法达到复用...
  • 请问udp的多路复用及校验和服务是什么意思?
  • IO多路复用

    2017-09-04 17:29:12
    提问一: Linux IO多路复用有 epoll, poll, select,知道epoll性能比其他几者要好。...IO多路复用是什么意思,在实际的应用中是指什么情况? 以及IO多路复用在一些异步web server中的实际应用,就好比
  • 什么是IO多路复用 为什么要有IO多路复用 作者总结 遵循学习新知识的三部曲:是什么?为什么?...作者前言:IO多路复用本质上是网络通信过程中的一个...IO 多路复用是什么意思? - 罗志宇的回答 - 知乎 有趣的比...
  • Linux I/O 多路复用

    2017-05-10 15:09:49
    IO多路复用是什么意思,在实际的应用中是指什么情况? 以及IO多路复用在一些异步web server中的实际应用,就好比nginx是怎样使用epoll来实现异步IO处理的,一个请求到来了,nginx使用epoll接收请求的过程是怎样的
  • SPU和SKU都是什么意思

    2019-12-16 19:56:32
    SPU和SKU都是什么意思 六月的帅 发布时间:18-09-1623:19 做电商的需要厘清两个概念SPU和SKU SPU = Standard Product Unit (标准产品单位)SPU是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的...
  • ApplicationContext 的分层规定了bean的界限以及可以复用的 bean。关于 ApplicationContext 层级可以参考官方文档...

空空如也

空空如也

1 2 3 4 5 ... 17
收藏数 326
精华内容 130
关键字:

复用是什么意思