您的位置:首页 > 软件问答

死亡空间2数据包(三星980 PRO 2TB 固态硬盘评测:凌绝顶 一览众山小)

导读死亡空间2数据包文章列表:1、三星980 PRO 2TB 固态硬盘评测:凌绝顶 一览众山小2、300块钱在拼多多买的平板电脑,还送12家影视会员!3、细思极恐!你的聊天内容可能被窃听?一次都没

死亡空间2数据包文章列表:

死亡空间2数据包(三星980 PRO 2TB 固态硬盘评测:凌绝顶 一览众山小)

三星980 PRO 2TB 固态硬盘评测:凌绝顶 一览众山小

2021年,得益于PC平台PCIe 4.0的全面开放、硬件的技术迭代、高计算类软件的盛行、信息化基础设施创新等因素影响,使得高性能、大容量的SSD成为驱动大数字化互联网的重要媒介。各大SSD厂商纷纷出台相应的高性能PCIe 4.0 SSD,加快PCIe 4.0的部署步伐,抢占先机,用一句话来表示SSD行业的现状,新时代,百花齐放最适合不过。

三星980PRO PCIe 4.0 NVMe SSD 2TB

如果追溯PCIe 4.0 SSD的开始,其实我们在19年就已经见识到了,但是由于当时的技术受到限制,导致那时的PCIe 4.0 SSD性能并不理想。回到当下,随着日前天花板级别的三星980PRO PCIe 4.0 NVMe SSD正式发布,也意味着,存储新时代也正式开启。

在此之前,我们已经见识到了三星980PRO PCIe 4.0 NVMe SSD的优势所在,而就在近日,三星再次完善产品线,2TB版本也随之到来,而笔者今天给大家带来的,正是三星980PRO PCIe 4.0 NVMe SSD 2TB版本的评测,按照惯例,在评测之前先来了解一下这款SSD都有哪些特点。

1、容量方面,最高为2TB,打破了性能与容量不并存这一现象。

2、搭载PCIe 4.0的Elpis新主控,第六代V-NAND闪存颗粒,性能、可靠性全面升级。

3、二代智能TurboWrite技术,保障连续大文件高速写入不掉速。

4、三位一体的智能散热机制、将温度控制在合理的范围,以保障硬盘寿命以及读写性能。

相信大家已将对这款刚刚发布的三星980PRO PCIe 4.0 NVMe SSD 2TB产生了浓厚的兴趣,接下来先来了解一下,这款SSD的一些基础参数。

01三星980PRO PCIe 4.0 NVMe SSD 产品概述

三星980PRO PCIe 4.0 NVMe SSD 2TB

三星980PRO PCIe 4.0 NVMe SSD在容量方面具有多重选择,其中包括,250GB、500GB、1TB、以及最新发布的2TB版本。2TB版本具有高容量,高性能的特性,定位于旗舰中的旗舰,更加适用于高端的电竞游戏以及专业的人士选择。

在尺寸方面,三星980PRO PCIe 4.0 NVMe SSD采用标准的紧凑型M.2 2280外形,能够轻松适配笔记本电脑、台式机等相关设备,具有不错的兼容性。

在耐用性方面,三星980PRO PCIe 4.0 NVMe SSD 2TB版本提供了1200TB的总写入字节数上限,按照我们每天写入50GB数据来计算,理论上可以使用67年之久,再加上三星的5年的售后保障,在耐用性方面,无须担心。

为了让用户更好的体验和管理三星980PRO PCIe4.0 SSD旗舰产品,三星研发了三星Magician管理软件。这是一款更加利于用户管理硬盘的软件,我们可以从中查看固态硬盘的型号,温度、固件、接口等关键信息。

相信大家已经对三星980PRO PCIe4.0 SSD已经有了一定的了解,接下来看一看三星980PRO PCIe4.0 SSD的内部情况。

02 三星980PRO PCIe4.0 SSD内部情况:主控 颗粒

三星980PRO PCIe4.0 SSD从主控到闪存再到缓存全部都由三星自主研发生产,这种端到端集成的做法让产品得到深度优化,可以使产品性能更优、质量更好、故障率更低。本次拆解的三星980PRO PCIe4.0 SSD是2TB版本。

主控方面,采用了三星针对PCIE4.0协议设计的全新主控,Elpis主控。Elpis主控采用三星自研的全新8nm制程工艺,全面支持PCIE4.0协议,同时能够满足下一代开发、计算等需求,新的Elpis主控支持128队列并行工作,支持128个I/O队列同步进行数据处理。

相较于上一代的Phoenix主控,队列数(32队列)提升了约400%,根据三星提供的数据,单个队列下,包含了超过64000命令集,这也就意味着三星Elpis主控内部的128个队列,可以同步处理最高超过800万个命令。

在颗粒方面,搭载的是三星自研第六代V-NAND闪存颗粒,根据官方介绍,第六代V-NAND颗粒在制程工艺上,充分利用三星独创的“通道孔蚀刻”技术,通过建立一个由100多个层组成的导电晶片堆栈,然后从上到下垂直穿孔,形成均匀的三维电荷阱闪存(CTF)单元,从而实现了,堆栈结构增加了大约40%的存储单元。

众所周知的是,随着每个单元区域中的晶片堆叠高度的增加,NAND闪存芯片更容易出现错误和读取延迟。为了克服这些限制,三星采用了速度优化的电路设计,使其能够实现比第五代V-NAND更快的数据传输速度,写入操作的时间少于450微秒(μs),读取操作的时间少于45μs。与上一代产品相比,性能提高了10%以上,而功耗降低了15%以上。

单位闪存容量的提升,使得笔者手上这款2TB容量的三星980PRO PCIe 4.0 NVMe SSD 2TB仅需要两颗闪存颗粒,便能为用户提供高达2TB大小的存储容量。

03 基准测试:探索消费级SSD的巅峰性能

测试平台介绍

为了能够发挥出三星980PRO PCIe4.0 SSD的实力所在,在处理器方面我们使用的是AMD最新发布的Ryzen 9 5950X,动态加速频率4.9GHz。16核心32线程。主板使用的是微星X570暗黑板,内存设置频率为3600MHz。

CrystalDiskMark测试

CrystalDiskMark是一款来自日本的老牌硬盘性能测试软件,它能够在保证了连续读写、512KB和4KB数据包随机读写性能,以及队列深度(Queue Depth)为32的情况下的4K随机性能等常规测试外,还在队列设置,性能描述,以及测试数据块选择上都进行了优化,更符合当下硬盘的测试需求。

在CrystalDiskMark测试测试中我们可以看到,三星980PRO PCIe4.0 SSD 2TB的顺序读取速度达到了7121.2MB/s,顺序写入速度达到了5176.4MB/s。

Txbench测试

Txbench是一款能够从不同队列,不同数据块进行存储性能测试的老牌软件。

在Txbench的测试中,三星980PRO PCIe4.0 SSD 2TB的最大顺序读取速度为6861.505MB/s,顺序写入速度为4973.357MB/s。

综合CrystalDiskMark、Txbench等三个软件的连续性能测试,三星980PRO PCIe4.0 SSD 2TB的成绩十分出色,与官方宣传的数据几乎一致。

04 4K随机测试

接下来进入4K随机测试环节,我们将使用AS SSD进行测试,AS SSD Benchmark是一个专门为SSD测试而设计的标准检测程序,它涵盖了持续性读写、单线程4KB随机读写、64线程4KB随机读写以及磁盘寻道时间等关键数据的测试,最后还会根据公式将成绩标准化,能比较科学的反映固态硬盘的真实性能。

在AS SSD测试中,我们可以看到三星980PRO PCIe4.0 SSD 2TB最大随机读取的IOPS值达到了637K iops,最大随机写入值则达到了798K iops,对比PCIE 3.0时代,提升十分显著。由于平台的缘故,在随机速度方面,并没有测出三星980PRO PCIe4.0 SSD 2TB真实性能。

05 稳定性测试

当然,固态硬盘的稳定性是一个重要环节,目前市面上有很多的固态硬盘会内置SLC加速机制,会导致在大数据传输过程中,前后性能会有明显的差异,无法真实反应产品的性能,所以本次测试使用HDTune软件,来验证三星980PRO PCIe4.0 SSD 2TB的真实效能。

鉴于当前HDTune软件文件基础项目自身的设计,无法进行超过200000M长度的写入测试,于是我们便设置200GB的文件长度进行实际读写的稳定性测试。

从HDTune软件测试中我们可以看到,三星980PRO PCIe4.0 SSD 2TB经过文件长度为200GB的写入后,没有任何掉速的表现,稳成一条直线。这也能够看出,三星980PRO PCIe4.0 SSD 2TB的动态缓存已经超过了200GB,这对于我们日常的数据大文件交互已经足够了。

为了进一步验证三星980PRO PCIe4.0 SSD 2TB的缓存容量,笔者进行了基准测试中的写入测试,文件长度为300GB,一次来测试三星980PRO PCIe4.0 SSD 2TB的缓存容量。

从测试中我们能够看出,三星980PRO PCIe4.0 SSD 2TB在连续写入240GB长度的文件后,出现了掉速,这也就意味着,三星980PRO PCIe4.0 SSD 2TB的缓存大小为240GB左右。

提到缓存,就不得不说三星独创的TurboWrite技术,借助TurboWrite,在固态硬盘中创建一个固定空间的高性能SLC写入缓冲区,在一定写入容量下维持SLC级别的高性能,进而实现了维持高性能的写入。此次全新升级的智能TurboWrite2.0,可自动识别用户的工作负载,并指定合适的SLC缓冲区,也就是说TurboWrite2.0能够智能的识别用户当前的存储工作负载,根据负载的不同,动态调整高性能SLC写入缓冲区配比;在缓存容量方面,相较于初代的TurboWrite机制,提供了高达5倍的缓冲区容量。

06 三位一体增强型散热机制

硬件产品随着性能的提升,随之而来的就是热量,计算量加快,热量增多是很容易理解的。此次三星980PRO PCIe4.0 SSD 2TB搭载的是三星独有的三位一体增强型散热机制,散热机制的核心分别是铜箔散热标签、Elpis控制器上的镍涂层,以及先进的动态散热保护(DTG)技术,从硬件到软件的全面覆盖,让SSD拥有了更好的散热表现。

根据三星官方提供的数据,Elpis控制器上的镍涂层在常规工作环境下,比对没有涂层的产品,二者平均温度差异在7℃;铜箔散热标签部分,带有铜箔散热标签能够延缓DTG散热保护触发时间接近30%左右;至于最为核心的动态散热保护(DTG)技术,则是三星自研一项能够监控固态硬盘产品温度,并为了提供过热保护的预警机制,它应用在三星品牌存储多款旗舰级产品之中,它的核心功能一言以蔽之,便是,人为的设定一个阈值,当固态硬盘工作温度达到阈值的时候,动态散热保护(DTG)技术便会被触发,减少和降低主控工作频率,直到温度降至安全区。

这也使得,三星980PRO PCIe4.0 SSD 2TB将拥有出色的散热能力,进一步保障SSD性能的稳定发挥。

07 写在最后

三星980PRO PCIe4.0 SSD 2TB可以说是三星目前最出色的一款高性能SSD,搭载了三星自主研发第六代V-NAND 3bit MLC颗粒,最新一代Elpis主控,集成了三星数年来在NAND闪存行业的技术积累和产品创新,实现了性能的突破。

那么,这款产品究竟会给我们带来哪些体验?从应用角度来说,三星980PRO PCIe4.0 SSD 2TB最高读取速度突破7000MB/s,最大写入速度突破5100MB/s,这对于我们日常的数据交互有着明显提升,例如文件拷贝,数据传输等。在随机速度方面,据官方了解,能够达到1000K IOPS,同比于PCIe 3.0 SSD,有了飞跃式的提升,这将会给我们带来更加流畅的体验,例如软件的启动、加载等。

站在行业角度,三星980PRO PCIe4.0 SSD 2TB的诞生,完美地解决了高性能SSD容量不足的短板,是PCIe 4.0SSD硬盘历程的必经之路,也为高性能SSD发展进程中写下浓墨重彩的一笔。

如果你对高性能且大容量的SSD有一定的兴趣,不妨尝试这款三星980PRO PCIe4.0 SSD 2TB,体验PC丝滑般的体验。感兴趣的同学快来吧~https://item.jd.com/100018171904.html

(7619122)

300块钱在拼多多买的平板电脑,还送12家影视会员!

更多奇葩好玩的科技互联网揭秘,欢迎点击右上角关注我~

最近托尼被 PDD 上一款平板电脑吸引了,号称 “ 超薄新款还送影视会员加 500 话费 ”,有这样的好事?

对托尼我来说,多一秒犹豫就是对自己钱包的不尊重,就那个顶配, 362 元的土豪金,来一个!

在等待了长达五六天后,终于到了! 包装还是蛮结实的嘛~

打开之后这大礼包也是蛮丰盛的,给大家看一下。

耳机,数据线、 3D 眼镜、移动 wifi 、智能运动手表、键盘等应有尽有,好久没遇到这么良心的卖家了,感觉为你想到了你能用到的一切。

不过这智能运动手表好像还没用没电了。。。

先不管那么多了,先开机吧!

屏幕尺寸大概是 7 英寸多,安卓系统,感觉界面有点老,像安卓 4.0 时代的界面,不过托尼也不敢确定,也许是独家定制的呢~

还是先用安兔兔测试一下吧,跑分接近 7 万分!

安卓 8.0 系统,屏幕分辨率 2560*1600 ,联发科新款 MT6797 处理器,也就是 Helio X20 ,运行内存 8GB 、存储空间 256G ,这妥妥的主流配置啊!

感觉托尼我这次赚大了,就这 256G 内存就够我看好多电影了!

想想还是有点不对,托尼我怎么说也是个老编辑,这 UI 界面怎么也不像安卓 8.0 啊,于是我尝试自己去官网下载一个安兔兔测试。

没想到。。。 提示 “ 已安装了存在签名冲突的同名数据包 ” ,

无法安装从官网下载的安兔兔。。。

我x。。。我就说没这么好的事情,原来这自带的安兔兔是为托尼量身定制。。。

不甘心的我又去下载了其它测试软件, AIDA64 和 CPU Z ,这下原形毕露了吧!

可以从这两款测试软件中发现,这款平板电脑的处理器不是它所说的 MT6797 ,而是一款 2013 年发布的低端处理器 MT6582 ,运行内存只有 1GB 。

屏幕分辨率只有 1280*800 ,就是一个普通的 16:10 比例的 720P 屏幕。但是系统依然显示为安卓 8.0 ,存储空间为 256G 。

这都是普通用户难以发现的地方,专业测试软件都不一定能测出来。

所以托尼把用数据线把平板连接电脑,再把托尼珍藏的一些电影往里面复制,结果发现当文件在 11G 左右的时候就已经无法复制进去,

再加上本身托尼已经下载的几个软件还有本身系统占用的内存,托尼大致推测,这部平板的实际存储空间应该在 16G 左右,而不是 256G 。

亏我还买了顶配,就是这样对待我这种尊贵客户的?

说是支持双卡双待,托尼插了两个卡上去,一点没有信号。( 不排除我卡没插好,虽然我插了很多次了。)

对了,后壳是我翘掉的,给大家看下内部,不过需要注意的是,这个后壳是胶水粘上去的,所以翘掉以后就粘不回去了。。。

做工不是很好

这都没事,我忍了,不是还送了价值 1755 元的 12 大视频 APP 的会员嘛?

哎,我大西瓜视频不是没有广告没有会员吗。。。不管了,有爱奇艺和优酷就行~

领取方式是这样的,在附送的礼包里有一张充值卡,

你先下载这个充值卡上的某通 APP 软件,然后把这个 500 元充值进去,

这个APP里面还有影视专区,不过一个月影视会员要用 20 元话费兑换,

不过想想有 500 块,兑换一下也无妨,哥有的是话费!

说好的 12 个APP呢,这只有七个啊。。。

word 天,真的能看会员电影???

而且这个软件还是真的能打电话的,就是一个我们以前经常用的网络电话 APP ,收费 2 毛钱一分钟, 500 块钱能用 2500 分钟,虽然网络电话通话质量不高,容易听不清,但考虑到同类 APP 充值同样通话时长市场价也是需要 100 多块钱的,这个托尼我赚了,还挺实用!

那看起来配置这么渣,这平板还能不能用?

托尼试了一下,看电视效果还 OK 。

打王者荣耀,居然也没问题!

这个真得感谢腾讯有点良心了,这游戏优化的可真好啊,让人泪流满面~

362 元的平板,能看电视、能打小游戏, 16G 内存、免费的网络电话还不错,可以看七大视频 APP 会员电影( 这应该是里面最好的东西了 ),对于一些朋友来说可能真的有用,虽然平板运行有点卡,但勉强能接受,毕竟大多用户买来应该还是看视频的,有会员美滋滋啊!

而卖家最大的问题就是故意欺瞒标高配置,如果你标明产品配置,正儿八经的卖,想必也会有人买,当然卖的数量可能没两万多件这么多~

但卖家就没想做长久生意,打一枪换个地方,这个店铺就这么一件商品,一件赚个 50 元,两三万个,就是几十万啊。。。

也许哪天拼多多变了,摇身一变做一个 “ 多多精选 ”,但现在很明显,它还在与假货劣质商品打的不可开交。

为什么会有那么多好评, 30 元好评返现说明了一切。。。

“ 突然有点心动?”

细思极恐!你的聊天内容可能被窃听?一次都没打开的App,却已向外传输数据…

来源:央视财经

现在,我们手机中都安装了各种应用,也就是各种App,的确方便了我们的工作、生活,但是也获取了我们大量的个人信息。一些App的推送能“精准”到你在想什么,它就给你推送什么。App的这种“正合我意”是怎么实现的?个人信息安全有没有风险呢?

App获取个人信息 用户感觉“被窃听”

△央视财经《第一时间》栏目视频

北京的苑庆攀最近有个疑惑,和朋友只在线下闲聊过的东西,第二天就出现在自己手机应用的推送里。

手机用户 苑庆攀:朋友说椰枣,过了一天我就刷到了关于椰枣的推荐视频。我觉得很惊讶,我除了说,没有任何搜索记录,咋就给我推荐了?

过于精准的推送内容,让苑庆攀感觉“后背发凉”。而这并不是苑庆攀一个人的感受。

手机用户 李先生:有的App使用的话就要把通讯录等信息都授权,我都不知道为什么要授权这些信息。

手机用户 纪女士:输入自己的手机号发送验证码之类的,第二天或者过几天就会有不知名的一些电话打进来,推销一些东西。

就在上周,工信部公布了2020年第二批侵害用户权益行为的App名单。在被点名的15个App中,有13个都涉及个人信息的过度收集,包括“私自收集个人信息”“超范围收集个人信息”“私自共享给第三方”等等,个人信息安全依然受到威胁。

中国信息通信研究院泰尔终端实验室信息安全部主任 宁华:在后台运行时,未经用户同意,按照一定的时间间隔定期调用系统API接口,频繁获取位置、应用列表等用户个人信息。这些新现象新问题已成为今年App个人信息保护治理的新重点。

而一些非法网络推广团伙也盯上了个人的信息。今年以来,公安部在15个省份开展打击贷款类网络诈骗犯罪,发现非法团伙就是将矛头指向有明确贷款意向的人员,根据他们在互联网、手机App等的浏览、搜索记录,分析其贷款意向,从而精准推送大量虚假贷款广告,并实施诈骗。

360集团安全研究员 俞奎:他拿到你的通讯录,又拿到短信,他可能知道你近段时间有借贷需求,这个时候他就可能会把这些数据进行二次贩卖,比如卖给一些专门做诈骗的人员。

手段隐蔽 多款App违规收集个人信息

面对越来越精准的推送,用户有着担心“被窃听”的焦虑,个人信息也确实存在过度获取的可能。为此,国家有关部门专门组建了App专项治理工作组,对强制授权、过度索权、超范围收集个人信息等现象进行专业的监管。精准推送怎么实现?过度获取怎么界定?

App专项治理工作组专家 何延哲:第一个数据包出现了,我们再等等,第二个数据包也出来了,我点开数据包,这里面就有一个是设备的IMEI号(移动设备标识号)的标识符。

在App专项治理工作组,针对个人信息保护的测试正在紧张地进行。检测工具显示,这款社交类App刚安装进手机,一次都还没有打开,却已经开始悄悄地向外传输数据。

App专项治理工作组专家 何延哲:App在隐私政策里没有提这件事,而且完全是隐瞒了它的自启动的方式,自己又把信息传到了自己的服务器上,是有实证的。明确是违法、违规收集的一种行为。

专家告诉记者,App获取的第一个信息,往往就是手机的IMEI号,也就是移动设备标识号。这个唯一的识别码,相当于手机的身份证。不管是经过用户同意“拿走”,还是不经允许“偷走”,App一旦获得了移动设备标识号,就为个性化推送奠定了基础。更可怕的是,专项治理工作组对大量App测试后发现,App获取的信息,不仅能自己用,甚至有部分App,会把信息传给第三方。

App专项治理工作组专家 何延哲:这是一款第三方SDK(软件开发工具包),它通过自启动之后的机制,把用户手机上的IMEI号这样的信息传走了。

专家介绍,在个别App内嵌入的第三方软件开发工具包超过50个。这些有着消息推送等功能的第三方工具包,行为更隐蔽,也是目前监管的难点。

360集团首席安全官 杜跃进:法律在一般情况下有一些认定,比如通讯录数据、短信的数据、点对点通信数据,是绝对不能被采集的,但是其他有一些地方其实就不那么清楚。

浙江大学网络空间安全研究中心研究员 周亚金:有一个所谓叫最小特权原则,就是说如果你不这么做,或者你把某一项你需要的权限给拿掉,或者你把你目前在后台做的某一个操作给拿掉,它不影响你App的正常功能,这个权限你实际上就不应该获取。

专家:获取技术在进步 信息保护在加码

近年来,有关部门定期针对App违法获取个人信息的行为进行曝光,针对App的各项隐私政策也在不断细化和规范。

专家分析,因为获取成本高、法律风险大,短期内,大家不必过于担心自己的语音、上传的图片等隐私信息被收集。

App专项治理工作组专家 何延哲:完全没必要用窃听这么复杂高级的手段,去针对某一个人的购物需求去做这样的事。造成精准推送的原因有很多,有可能是你的好友搜了一个商品,它可能知道你们是好友关系,可能就会给这些人都会推这样的信息,但是你感觉好像是自己的原因,好像被“窃听”了。

不过,专家也提醒,越来越多新的技术手段正在降低用户信息获取的成本和风险。今年,浙江大学的最新研究成果显示,手机App甚至可以利用手机内置的加速度传感器,采集手机扬声器所发出的声音振动频率。这样的技术,可以在用户不知情的情况下,绕开隐私协议,合法地获取语音信息。

360集团首席安全官 杜跃进 :普通用户能做的很有限,最多就是看一看App里面的隐私声明,但是稍微大一点的App,也都会知道在法规上文字上是不会有问题的。

浙江大学网络空间安全研究中心研究员周亚金 :一些厂商可以提出绕过隐私协议的一些机制,来继续访问用户的隐私行为,但是也不弹窗,也不会被发现,这个其实技术上的攻防是一直存在的。

与此同时,个人信息的保护也一直在不断加强。去年12月,国家网信办出台《App违法违规收集使用个人信息行为认定方法》,强化用户的知情权和决定权。

App专项治理工作组专家 何延哲:能够关闭这也是一种控制,广告太精准了,恐怕最后起到的效果不一定很好,这里面就需要制定一些规则,比如用户画像,不一定做一些直接的画像,比如可能这一群人喜欢足球、喜欢读书,这是一种爱好习惯,就用这种宽泛性的爱好习惯来代替对于个人的精准的需求。

超详细的Proactor模式&Reactor模式解析

一、简介

服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种:

(1)同步阻塞IO(BlockingIO):即传统的IO模型。

(2)同步非阻塞IO(Non-blockingIO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK。注意这里所说的NIO并非Java的NIO(NewIO)库。

(3)IO多路复用(IOMultiplexing):即经典的Reactor设计模式,有时也称为异步阻塞IO,Java中的Selector和Linux中的epoll都是这种模型。

(4)异步IO(AsynchronousIO):即经典的Proactor设计模式,也称为异步非阻塞IO。

  同步和异步的概念描述的是用户线程与内核的交互方式:同步是指用户线程发起IO请求后需要等待或者轮询内核IO操作完成后才能继续执行;而异步是指用户线程发起IO请求后仍继续执行,当内核IO操作完成后会通知用户线程,或者调用用户线程注册的回调函数。

  阻塞和非阻塞的概念描述的是用户线程调用内核IO操作的方式:阻塞是指IO操作需要彻底完成后才返回到用户空间;而非阻塞是指IO操作被调用后立即返回给用户一个状态值,无需等到IO操作彻底完成。

  另外,RichardStevens在《Unix网络编程》卷1中提到的基于信号驱动的IO(SignalDrivenIO)模型,由于该模型并不常用,本文不作涉及。接下来,我们详细分析四种常见的IO模型的实现原理。为了方便描述,我们统一使用IO的读操作作为示例。

二、同步阻塞IO

同步阻塞IO模型是最简单的IO模型,用户线程在内核进行IO操作时被阻塞。

  如图1所示,用户线程通过系统调用read发起IO读操作,由用户空间转到内核空间。内核等到数据包到达后,然后将接收的数据拷贝到用户空间,完成read操作。

用户线程使用同步阻塞IO模型的伪代码描述为:

1 {2 read(socket, buffer);3 process(buffer);4 }

  即用户需要等待read将socket中的数据读取到buffer后,才继续处理接收的数据。整个IO请求的过程中,用户线程是被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对CPU的资源利用率不够。

三、同步非阻塞IO

同步非阻塞IO是在同步阻塞IO的基础上,将socket设置为NONBLOCK。这样做用户线程可以在发起IO请求后可以立即返回。

  如图2所示,由于socket是非阻塞的方式,因此用户线程发起IO请求时立即返回。但并未读取到任何数据,用户线程需要不断地发起IO请求,直到数据到达后,才真正读取到数据,继续执行。

用户线程使用同步非阻塞IO模型的伪代码描述为:

1 {2 while(read(socket, buffer) != SUCCESS);3 process(buffer);4 }

  即用户需要不断地调用read,尝试读取socket中的数据,直到读取成功后,才继续处理接收的数据。整个IO请求的过程中,虽然用户线程每次发起IO请求后可以立即返回,但是为了等到数据,仍需要不断地轮询、重复请求,消耗了大量的CPU的资源。一般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性。

四、IO多路复用

  IO多路复用模型是建立在内核提供的多路分离函数select、poll以及epoll基础之上的,使用这些函数可以避免同步非阻塞IO模型中轮询等待的问题,因为用户线程将这个轮询的过程将给内核来执行,而自己则表现为阻塞态。

  如图3所示,用户首先将需要进行IO操作的socket添加到select中,然后阻塞等待select系统调用返回。当数据到达时,socket被激活,select函数返回。用户线程正式发起read请求,读取数据并继续执行。

  从流程上来看,使用select函数进行IO请求和同步阻塞模型没有太大的区别,甚至还多了添加监视socket,以及调用select函数的额外操作,效率更差。但是,使用select以后最大的优势是用户可以在一个线程内同时处理多个socket的IO请求。用户可以注册多个socket,然后不断地调用select读取被激活的socket,即可达到在同一个线程内同时处理多个IO请求的目的。而在同步阻塞模型中,必须通过多线程的方式才能达到这个目的。

用户线程使用select函数的伪代码描述为:

1 { 2 select(socket); 3 while(1) 4 { 5 sockets = select(); 6 for(socket in sockets) { 7 if(can_read(socket)) { 8 read(socket, buffer); 9 process(buffer);10 }11 }12 }13 }

  其中while循环前将socket添加到select监视中,然后在while内一直调用select获取被激活的socket,一旦socket可读,便调用read函数将socket中的数据读取出来。

  然而,使用select函数的优点并不仅限于此。虽然上述方式允许单线程内处理多个IO请求,但是每个IO请求的过程还是阻塞的(在select函数上阻塞),平均时间甚至比同步阻塞IO模型还要长。如果用户线程只注册自己感兴趣的socket或者IO请求,然后去做自己的事情,等到数据到来时再进行处理,则可以提高CPU的利用率。

  IO多路复用模型使用了Reactor设计模式实现了这一机制。

图4Reactor设计模式

  如图4所示,EventHandler抽象类表示IO事件处理器,它拥有IO文件句柄Handle(通过get_handle获取),以及对Handle的操作handle_event(读/写等)。继承于EventHandler的子类可以对事件处理器的行为进行定制。Reactor类用于管理EventHandler(注册、删除等),并使用handle_events实现事件循环,不断调用同步事件多路分离器(一般是内核)的多路分离函数select,只要某个文件句柄被激活(可读/写等),select就返回(阻塞),handle_events就会调用与文件句柄关联的事件处理器的handle_event进行相关操作。

  如图5所示,通过Reactor的方式,可以将用户线程轮询IO操作状态的工作统一交给handle_events事件循环进行处理。用户线程注册事件处理器之后可以继续执行做其他的工作(异步),而Reactor线程负责调用内核的select函数检查socket状态。当有socket被激活时,则通知相应的用户线程(或执行用户线程的回调函数),执行handle_event进行数据读取、处理的工作。由于select函数是阻塞的,因此多路IO复用模型也被称为异步阻塞IO模型。注意,这里的所说的阻塞是指select函数执行时线程被阻塞,而不是指socket。一般在使用IO多路复用模型时,socket都是设置为NONBLOCK的,不过这并不会产生影响,因为用户发起IO请求时,数据已经到达了,用户线程(相当于工作线程)一定不会被阻塞。

  用户线程使用IO多路复用模型的伪代码描述为:

1 voidUserEventHandler::handle_event(){2 if(can_read(socket)){3 read(socket,buffer);4 process(buffer);5 }6 }7 {8 Reactor.register(newUserEventHandler(socket));9 }

  用户需要重写EventHandler的handle_event函数进行读取数据、处理数据的工作,用户线程只需要将自己的EventHandler注册到Reactor即可。Reactor中handle_events事件循环的伪代码大致如下。

1 Reactor::handle_events(){2 while(1){3 sockets=select();4 for(socketinsockets){5 get_event_handler(socket).handle_event();6 }7 }8 }

  事件循环不断地调用select获取被激活的socket,然后根据获取socket对应的EventHandler,执行器handle_event函数即可。IO多路复用是最常使用的IO模型,但是其异步程度还不够“彻底”,因为它使用了会阻塞线程的select系统调用。因此IO多路复用只能称为异步阻塞IO,而非真正的异步IO。

相关视频推荐

linux多线程之epoll原理剖析与reactor原理及应用

网络原理tcp/udp,网络编程epoll/reactor,面试中正经“八股文”

[linux]一个让性能飞起的解决方案,异步处理到底有哪些不一样

需要C/C Linux服务器架构师学习资料加qun812855908获取(资料包括C/C ,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享

五、异步IO

  “真正”的异步IO需要操作系统更强的支持。在IO多路复用模型中,事件循环将文件句柄的状态事件通知给用户线程,由用户线程自行读取数据、处理数据。而在异步IO模型中,当用户线程收到通知时,数据已经被内核读取完毕,并放在了用户线程指定的缓冲区内,内核在IO完成后通知用户线程直接使用即可。

  异步IO模型使用了Proactor设计模式实现了这一机制。

  如图6,Proactor模式和Reactor模式在结构上比较相似,不过在用户(Client)使用方式上差别较大。Reactor模式中,用户线程通过向Reactor对象注册感兴趣的事件监听,然后事件触发时调用事件处理函数。而Proactor模式中,用户线程将AsynchronousOperation(读/写等)、Proactor以及操作完成时的CompletionHandler注册到AsynchronousOperationProcessor。AsynchronousOperationProcessor使用Facade模式提供了一组异步操作API(读/写等)供用户使用,当用户线程调用异步API后,便继续执行自己的任务。AsynchronousOperationProcessor会开启独立的内核线程执行异步操作,实现真正的异步。当异步IO操作完成时,AsynchronousOperationProcessor将用户线程与AsynchronousOperation一起注册的Proactor和CompletionHandler取出,然后将CompletionHandler与IO操作的结果数据一起转发给Proactor,Proactor负责回调每一个异步操作的事件完成处理函数handle_event。虽然Proactor模式中每个异步操作都可以绑定一个Proactor对象,但是一般在操作系统中,Proactor被实现为Singleton模式,以便于集中化分发操作完成事件。

  如图7所示,异步IO模型中,用户线程直接使用内核提供的异步IOAPI发起read请求,且发起后立即返回,继续执行用户线程代码。不过此时用户线程已经将调用的AsynchronousOperation和CompletionHandler注册到内核,然后操作系统开启独立的内核线程去处理IO操作。当read请求的数据到达时,由内核负责读取socket中的数据,并写入用户指定的缓冲区中。最后内核将read的数据和用户线程注册的CompletionHandler分发给内部Proactor,Proactor将IO完成的信息通知给用户线程(一般通过调用用户线程注册的完成事件处理函数),完成异步IO。

用户线程使用异步IO模型的伪代码描述为:

1 voidUserCompletionHandler::handle_event(buffer){2 process(buffer);3 }4 {5 aio_read(socket,newUserCompletionHandler);6 }

  用户需要重写CompletionHandler的handle_event函数进行处理数据的工作,参数buffer表示Proactor已经准备好的数据,用户线程直接调用内核提供的异步IOAPI,并将重写的CompletionHandler注册即可。

  相比于IO多路复用模型,异步IO并不十分常用,不少高性能并发服务程序使用IO多路复用模型 多线程任务处理的架构基本可以满足需求。况且目前操作系统对异步IO的支持并非特别完善,更多的是采用IO多路复用模型模拟异步IO的方式(IO事件触发时不直接通知用户线程,而是将数据读写完毕后放到用户指定的缓冲区中)。Java7之后已经支持了异步IO,感兴趣的读者可以尝试使用。

六、reactor总结

6.1 背景

  如果要让服务器服务多个客户端,那么最直接的方式就是为每一条连接创建线程。

  其实创建进程也是可以的,原理是一样的,进程和线程的区别在于线程比较轻量级些,线程的创建和线程间切换的成本要小些,为了描述简述,后面都以线程为例。

  处理完业务逻辑后,随着连接关闭后线程也同样要销毁了,但是这样不停地创建和销毁线程,不仅会带来性能开销,也会造成浪费资源,而且如果要连接几万条连接,创建几万个线程去应对也是不现实的。

  要这么解决这个问题呢?我们可以使用「资源复用」的方式。

  也就是不用再为每个连接创建线程,而是创建一个「线程池」,将连接分配给线程,然后一个线程可以处理多个连接的业务。

  不过,这样又引来一个新的问题,线程怎样才能高效地处理多个连接的业务?

  当一个连接对应一个线程时,线程一般采用「read -> 业务处理 -> send」的处理流程,如果当前连接没有数据可读,那么线程会阻塞在 read 操作上( socket 默认情况是阻塞 I/O),不过这种阻塞方式并不影响其他线程。

  但是引入了线程池,那么一个线程要处理多个连接的业务,线程在处理某个连接的 read 操作时,如果遇到没有数据可读,就会发生阻塞,那么线程就没办法继续处理其他连接的业务。

  要解决这一个问题,最简单的方式就是将 socket 改成非阻塞,然后线程不断地轮询调用 read 操作来判断是否有数据,这种方式虽然该能够解决阻塞的问题,但是解决的方式比较粗暴,因为轮询是要消耗 CPU 的,而且随着一个线程处理的连接越多,轮询的效率就会越低。

  上面的问题在于,线程并不知道当前连接是否有数据可读,从而需要每次通过 read 去试探。

  那有没有办法在只有当连接上有数据的时候,线程才去发起读请求呢?答案是有的,实现这一技术的就是 I/O 多路复用。

6.2 IO多路复用

​  我们熟悉的 select/poll/epoll 就是内核提供给用户态的多路复用系统调用,线程可以通过一个系统调用函数从内核中获取多个事件。

  select/poll/epoll 是如何获取网络事件的呢?

  在获取事件时,先把我们要关心的连接传给内核,再由内核检测:

如果没有事件发生,线程只需阻塞在这个系统调用,而无需像前面的线程池方案那样轮训调用 read 操作来判断是否有数据。

如果有事件发生,内核会返回产生了事件的连接,线程就会从阻塞状态返回,然后在用户态中再处理这些连接对应的业务即可。

  当下开源软件能做到网络高性能的原因就是 I/O 多路复用吗?

  是的,基本是基于 I/O 多路复用,用过 I/O 多路复用接口写网络程序的同学,肯定知道是面向过程的方式写代码的,这样的开发的效率不高。

  于是,大佬们基于面向对象的思想,对 I/O 多路复用作了一层封装,让使用者不用考虑底层网络 API 的细节,只需要关注应用代码的编写。大佬们还为这种模式取了个让人第一时间难以理解的名字:Reactor 模式。

6.3 简介

Reactor 翻译过来的意思是「反应堆」,可能大家会联想到物理学里的核反应堆,实际上并不是的这个意思。

这里的反应指的是「对事件反应」,也就是来了一个事件,Reactor 就有相对应的反应/响应。

事实上,Reactor 模式也叫 Dispatcher 模式,我觉得这个名字更贴合该模式的含义,即 I/O 多路复用监听事件,收到事件后,根据事件类型分配(Dispatch)给某个进程 / 线程。

Reactor 模式主要由 Reactor 和处理资源池这两个核心部分组成,它俩负责的事情如下:

Reactor 负责监听和分发事件,事件类型包含连接事件、读写事件;

处理资源池负责处理事件,如 read -> 业务逻辑 -> send;

Reactor 模式是灵活多变的,可以应对不同的业务场景,灵活在于:

Reactor 的数量可以只有一个,也可以有多个;

处理资源池可以是单个进程 / 线程,也可以是多个进程 /线程;

将上面的两个因素排列组设一下,理论上就可以有 4 种方案选择:

单 Reactor 单进程 / 线程;

单 Reactor 多进程 / 线程;

多 Reactor 单进程 / 线程;

多 Reactor 多进程 / 线程;

其中,「多 Reactor 单进程 / 线程」实现方案相比「单 Reactor 单进程 / 线程」方案,不仅复杂而且也没有性能优势,因此实际中并没有应用。

方案具体使用进程还是线程,要看使用的编程语言以及平台有关:

Java 语言一般使用线程,比如 Netty;

C 语言使用进程和线程都可以,例如 Nginx 使用的是进程,Memcache 使用的是线程。

接下来,分别介绍这三个经典的 Reactor 方案。

6.4 单 Reactor 单进程 / 线程

6.4.1 流程图

  一般来说,C 语言实现的是「单 Reactor 单进程」的方案,因为 C 语编写完的程序,运行后就是一个独立的进程,不需要在进程中再创建线程。

  而 Java 语言实现的是「单 Reactor 单线程」的方案,因为 Java 程序是跑在 Java 虚拟机这个进程上面的,虚拟机中有很多线程,我们写的 Java 程序只是其中的一个线程而已。

我们来看看「单 Reactor 单进程」的方案示意图:

6.4.2 流程图分析

可以看到进程里有 Reactor、Acceptor、Handler 这三个对象:

Reactor 对象的作用是监听和分发事件;

Acceptor 对象的作用是获取连接;

Handler 对象的作用是处理业务;

对象里的 select、accept、read、send 是系统调用函数,dispatch 和 「业务处理」是需要完成的操作,其中 dispatch 是分发事件操作。

接下来,介绍下「单 Reactor 单进程」这个方案:

Reactor 对象通过 select (IO 多路复用接口) 监听事件,收到事件后通过 dispatch 进行分发,具体分发给 Acceptor 对象还是 Handler 对象,还要看收到的事件类型;

如果是连接建立的事件,则交由 Acceptor 对象进行处理,Acceptor 对象会通过 accept 方法 获取连接,并创建一个 Handler 对象来处理后续的响应事件;

如果不是连接建立事件, 则交由当前连接对应的 Handler 对象来进行响应;

Handler 对象通过 read -> 业务处理 -> send 的流程来完成完整的业务流程。

单 Reactor 单进程的方案因为全部工作都在同一个进程内完成,所以实现起来比较简单,不需要考虑进程间通信,也不用担心多进程竞争。

6.4.3 缺点

但是,这种方案存在 2 个缺点:

第一个缺点,因为只有一个进程,无法充分利用 多核 CPU 的性能;

第二个缺点,Handler 对象在业务处理时,整个进程是无法处理其他连接的事件的,如果业务处理耗时比较长,那么就造成响应的延迟;

6.4.4 应用场景和实例

  所以,单 Reactor 单进程的方案不适用计算机密集型的场景,只适用于业务处理非常快速的场景。

  Redis 是由 C 语言实现的,它采用的正是「单 Reactor 单进程」的方案,因为 Redis 业务处理主要是在内存中完成,操作的速度是很快的,性能瓶颈不在 CPU 上,所以 Redis 对于命令的处理是单进程的方案。Redis的瓶颈最有可能是机器内存的大小或者网络带宽。

  Redis将数据存放在内存当中,这也就意味着,Redis在操作数据时,不需要进行磁盘I/O。磁盘I/O是一个比较耗时的操作,所以对于需要进行磁盘I/O的程序,我们可以使用多线程,在某个线程进行I/O时,CPU切换到当前程序的其他线程执行,以此减少CPU的等待时间。而Redis直接操作内存中的数据,所以使用多线程并不能有效提升效率,相反,使用多线程反倒会因为需要进行线程的切换而降低效率。

除此之外,使用多线程的话,多个线程间进行同步,保证线程的安全,也是需要开销的。尤其是Redis的数据结构都是一些实现较为简单的集合结构,若使用多线程,将会频繁地发生线程冲突,线程的竞争频率较高,反倒会拖慢Redis的响应速度。

综上所述,Redis为了保持简单和高效,自然而然地就使用了单线程。

6.5 单 Reactor 单进程 / 线程

6.5.1 流程图

如果要克服「单 Reactor 单线程 / 进程」方案的缺点,那么就需要引入多线程 / 多进程,这样就产生了单 Reactor 多线程 / 多进程的方案。

闻其名不如看其图,先来看看「单 Reactor 多线程」方案的示意图如下:

6.5.2 流程图分析

详细说一下这个方案:

Reactor 对象通过 select (IO 多路复用接口) 监听事件,收到事件后通过 dispatch 进行分发,具体分发给 Acceptor 对象还是 Handler 对象,还要看收到的事件类型;

如果是连接建立的事件,则交由 Acceptor 对象进行处理,Acceptor 对象会通过 accept 方法 获取连接,并创建一个 Handler 对象来处理后续的响应事件;

如果不是连接建立事件, 则交由当前连接对应的 Handler 对象来进行响应;

上面的三个步骤和单 Reactor 单线程方案是一样的,接下来的步骤就开始不一样了:

Handler 对象不再负责业务处理,只负责数据的接收和发送,Handler 对象通过 read 读取到数据后,会将数据发给子线程里的 Processor 对象进行业务处理;

子线程里的 Processor 对象就进行业务处理,处理完后,将结果发给主线程中的 Handler 对象,接着由 Handler 通过 send 方法将响应结果发送给 client;

6.5.3 优点和缺点

6.5.3.1 优点

  单 Reator 多线程的方案优势在于能够充分利用多核 CPU 的能,那既然引入多线程,那么自然就带来了多线程竞争资源的问题。

6.5.3.2 缺点

资源共享导致的竞争

  例如,子线程完成业务处理后,要把结果传递给主线程的 Reactor 进行发送,这里涉及共享数据的竞争。

  要避免多线程由于竞争共享资源而导致数据错乱的问题,就需要在操作共享资源前加上互斥锁,以保证任意时间里只有一个线程在操作共享资源,待该线程操作完释放互斥锁后,其他线程才有机会操作共享数据。

单 Reactor 多进程的通信(资源共享)

  聊完单 Reactor 多线程的方案,接着来看看单 Reactor 多进程的方案。

  事实上,单 Reactor 多进程相比单 Reactor 多线程实现起来很麻烦,主要因为要考虑子进程 <-> 父进程的双向通信,并且父进程还得知道子进程要将数据发送给哪个客户端。

而多线程间可以共享数据,虽然要额外考虑并发问题,但是这远比进程间通信的复杂度低得多,因此实际应用中也看不到单 Reactor 多进程的模式。

单 Reactor 的压力

  另外,「单 Reactor」的模式还有个问题,因为一个 Reactor 对象承担所有事件的监听和响应,而且只在主线程中运行,在面对瞬间高并发的场景时,容易成为性能的瓶颈的地方。

6.6 多 Reactor 多进程 / 线程

6.6.1 流程图

  要解决「单 Reactor」的问题,就是将「单 Reactor」实现成「多 Reactor」,这样就产生了第 多 Reactor 多进程 / 线程的方案。

  老规矩,闻其名不如看其图。多 Reactor 多进程 / 线程方案的示意图如下(以线程为例):

6.6.2 流程图分析

方案详细说明如下:

主线程中的 MainReactor 对象通过 select 监控连接建立事件,收到事件后通过 Acceptor 对象中的 accept 获取连接,将新的连接分配给某个子线程;

子线程中的 SubReactor 对象将 MainReactor 对象分配的连接加入 select 继续进行监听,并创建一个 Handler 用于处理连接的响应事件。

如果有新的事件发生时,SubReactor 对象会调用当前连接对应的 Handler 对象来进行响应。

Handler 对象通过 read -> 业务处理 -> send 的流程来完成完整的业务流程。

多 Reactor 多线程的方案虽然看起来复杂的,但是实际实现时比单 Reactor 多线程的方案要简单的多,原因如下:

主线程和子线程分工明确,主线程只负责接收新连接,子线程负责完成后续的业务处理。

主线程和子线程的交互很简单,主线程只需要把新连接传给子线程,子线程无须返回数据,直接就可以在子线程将处理结果发送给客户端。

6.6.3 应用场景和实例

  大名鼎鼎的两个开源软件 Netty 和 Memcache 都采用了「多 Reactor 多线程」的方案。

  采用了「多 Reactor 多进程」方案的开源软件是 Nginx,不过方案与标准的多 Reactor 多进程有些差异。

  具体差异表现在主进程中仅仅用来初始化 socket,并没有创建 mainReactor 来 accept 连接,而是由子进程的 Reactor 来 accept 连接,通过锁来控制一次只有一个子进程进行 accept(防止出现惊群现象),子进程 accept 新连接后就放到自己的 Reactor 进行处理,不会再分配给其他子进程。

七、Proactor总结

7.1 背景

  前面提到的 Reactor 是非阻塞同步网络模式,而 Proactor 是异步网络模式。

7.1.1 阻塞 I/O分析

  先来看看阻塞 I/O,当用户程序执行 read ,线程会被阻塞,一直等到内核数据准备好,并把数据从内核缓冲区拷贝到应用程序的缓冲区中,当拷贝过程完成,read 才会返回。

注意,阻塞等待的是「内核数据准备好」和「数据从内核态拷贝到用户态」这两个过程。过程如下图:

7.1.2 阻塞 I/O分析

  知道了阻塞 I/O ,来看看非阻塞 I/O,非阻塞的 read 请求在数据未准备好的情况下立即返回,可以继续往下执行,此时应用程序不断轮询内核,直到数据准备好,内核将数据拷贝到应用程序缓冲区,read 调用才可以获取到结果。过程如下图:

  注意,这里最后一次 read 调用,获取数据的过程,是一个同步的过程,是需要等待的过程。这里的同步指的是内核态的数据拷贝到用户程序的缓存区这个过程。

7.1.3 同步和异步分析

  举个例子,如果 socket 设置了 O_NONBLOCK 标志,那么就表示使用的是非阻塞 I/O 的方式访问,而不做任何设置的话,默认是阻塞 I/O。

  因此,无论 read 和 send 是阻塞 I/O,还是非阻塞 I/O 都是同步调用。因为在 read 调用时,内核将数据从内核空间拷贝到用户空间的过程都是需要等待的,也就是说这个过程是同步的,如果内核实现的拷贝效率不高,read 调用就会在这个同步过程中等待比较长的时间。

  而真正的异步 I/O 是「内核数据准备好」和「数据从内核态拷贝到用户态」这两个过程都不用等待。

  当我们发起 aio_read (异步 I/O) 之后,就立即返回,内核自动将数据从内核空间拷贝到用户空间,这个拷贝过程同样是异步的,内核自动完成的,和前面的同步操作不一样,应用程序并不需要主动发起拷贝动作。过程如下图:

​举个你去饭堂吃饭的例子,你好比应用程序,饭堂好比操作系统。

  阻塞 I/O 好比,你去饭堂吃饭,但是饭堂的菜还没做好,然后你就一直在那里等啊等,等了好长一段时间终于等到饭堂阿姨把菜端了出来(数据准备的过程),但是你还得继续等阿姨把菜(内核空间)打到你的饭盒里(用户空间),经历完这两个过程,你才可以离开。

  非阻塞 I/O 好比,你去了饭堂,问阿姨菜做好了没有,阿姨告诉你没,你就离开了,过几十分钟,你又来饭堂问阿姨,阿姨说做好了,于是阿姨帮你把菜打到你的饭盒里,这个过程你是得等待的。

  异步 I/O 好比,你让饭堂阿姨将菜做好并把菜打到饭盒里后,把饭盒送到你面前,整个过程你都不需要任何等待。

  很明显,异步 I/O 比同步 I/O 性能更好,因为异步 I/O 在「内核数据准备好」和「数据从内核空间拷贝到用户空间」这两个过程都不用等待。

7.2 Proactor

7.2.1 Proactor和Reactor对比

  Proactor 正是采用了异步 I/O 技术,所以被称为异步网络模型。现在我们再来理解 Reactor 和 Proactor 的区别,就比较清晰了。

Reactor 是非阻塞同步网络模式,感知的是就绪可读写事件。需要注意的是,这里所属的非阻塞是指使用的socket是非阻塞的,但是用户进程依然是阻塞的,与前面的分析并不冲突,在每次感知到有事件发生(比如可读就绪事件)后,就需要应用进程主动调用 read 方法来完成数据的读取,也就是要应用进程主动将 socket 接收缓存中的数据读到应用进程内存中,这个过程是同步的,读取完数据后应用进程才能处理数据。

Proactor 是异步网络模式, 感知的是已完成的读写事件。在发起异步读写请求时,需要传入数据缓冲区的地址(用来存放结果数据)等信息,这样系统内核才可以自动帮我们把数据的读写工作完成,这里的读写工作全程由操作系统来做,并不需要像 Reactor 那样还需要应用进程主动发起 read/write 来读写数据,操作系统完成读写工作后,就会通知应用进程直接处理数据。

  因此,Reactor 可以理解为「来了事件操作系统通知应用进程,让应用进程来处理」,而 Proactor 可以理解为「来了事件操作系统来处理,处理完再通知应用进程」。这里的「事件」就是有新连接、有数据可读、有数据可写的这些 I/O 事件这里的「处理」包含从驱动读取到内核以及从内核读取到用户空间。

  举个实际生活中的例子,Reactor 模式就是快递员在楼下,给你打电话告诉你快递到你家小区了,你需要自己下楼来拿快递。而在 Proactor 模式下,快递员直接将快递送到你家门口,然后通知你。

无论是 Reactor,还是 Proactor,都是一种基于「事件分发」的网络编程模式,区别在于 Reactor 模式是基于「待完成」的 I/O 事件,而 Proactor 模式则是基于「已完成」的 I/O 事件。

7.2.2 Proactor 模式的示意图

7.2.3 Proactor 模式的示意图分析

介绍一下 Proactor 模式的工作流程:

Proactor Initiator 负责创建 Proactor 和 Handler 对象,并将 Proactor 和 Handler 都通过Asynchronous Operation Processor 注册到内核;

Asynchronous Operation Processor 负责处理注册请求,并处理 I/O 操作;

Asynchronous Operation Processor 完成 I/O 操作后通知 Proactor;

Proactor 根据不同的事件类型回调不同的 Handler 进行业务处理;

Handler 完成业务处理;

7.3 Proactor 模式的问题

  可惜的是,在 Linux 下的异步 I/O 是不完善的,aio系列函数是由 POSIX 定义的异步操作接口,不是真正的操作系统级别支持的,而是在用户空间模拟出来的异步,并且仅仅支持基于本地文件的 aio 异步操作,网络编程中的 socket 是不支持的,这也使得基于 Linux 的高性能网络程序都是使用 Reactor 方案,linux也有内核级别的异步IO操作函数libaio,但是存在着一定的缺陷,所有的文件打开的时候必须包含书O_DIRECT标志,并非所有的文件系统都支持该类接口,如果不支持,IO操作就会变成阻塞的,当然,如果你不添加O_DIRECT标志,它锁使用的IO操作也是阻塞的。

  而 Windows 里实现了一套完整的支持 socket 的异步编程接口,这套接口就是 IOCP,是由操作系统级别实现的异步 I/O,真正意义上异步 I/O,因此在 Windows 里实现高性能网络程序可以使用效率更高的 Proactor 方案。

7.4 小结

常见的 Reactor 实现方案有三种。

  第一种方案单 Reactor 单进程 / 线程,不用考虑进程间通信以及数据同步的问题,因此实现起来比较简单,这种方案的缺陷在于无法充分利用多核 CPU,而且处理业务逻辑的时间不能太长,否则会延迟响应,所以不适用于计算机密集型的场景,适用于业务处理快速的场景,比如 Redis 采用的是单 Reactor 单进程的方案。

  第二种方案单 Reactor 多线程,通过多线程的方式解决了方案一的缺陷,但它离高并发还差一点距离,差在只有一个 Reactor 对象来承担所有事件的监听和响应,而且只在主线程中运行,在面对瞬间高并发的场景时,容易成为性能的瓶颈的地方。

  第三种方案多 Reactor 多进程 / 线程,通过多个 Reactor 来解决了方案二的缺陷,主 Reactor 只负责监听事件,响应事件的工作交给了从 Reactor,Netty 和 Memcache 都采用了「多 Reactor 多线程」的方案,Nginx 则采用了类似于 「多 Reactor 多进程」的方案。

  Reactor 可以理解为「来了事件操作系统通知应用进程,让应用进程来处理」,而 Proactor 可以理解为「来了事件操作系统来处理,处理完再通知应用进程」。

  因此,真正的大杀器还是 Proactor,它是采用异步 I/O 实现的异步网络模型,感知的是已完成的读写事件,而不需要像 Reactor 感知到事件后,还需要调用 read 来从内核中获取数据。

  不过,无论是 Reactor,还是 Proactor,都是一种基于「事件分发」的网络编程模式,区别在于 Reactor 模式是基于「待完成」的 I/O 事件,而 Proactor 模式则是基于「已完成」的 I/O 事件,这个完成指的是数据的读取已经完成,实际上单Reactor多线程就是一种模拟的Proactor。

铠侠 极至光速系列内存卡评测:经典红白复刻,唯有品质依旧

[PConline 评测]自从东芝存储更名为铠侠以后,整个品牌的各类产品包装配色都随之发生了变换,尤其是SD卡产品更是一改往日传统低调的黑色风格,选择了更为年轻化的配色,比如今天这款铠侠 EXCERIA PLUS 极至光速系列 存储卡,就采用了骚气十足的红色,主打高性能,相信会是摄像爱好者的最爱,现在就让笔者来分享一下上手体验。

包装&外观:辨识度极高

铠侠 EXCERIA PLUS 存储卡的外包装十分简洁,包装整体以品红色为主,正中则是带云台的摄像机的图案,表明了这款储存卡的主要使用场景,适合那些追求高速稳定的摄影与录像用户群体。

在包装的最下面是品牌的Logo,而最上面则是产品的一些简单信息,如型号、容量、名称等,这款存储卡支持V30、U3、class 10等技术协议,是铠侠目前在高性能TF卡市场上最优的产品,充分保障了我们对于4K视频拍摄的需求,帮用户清晰纪录每一瞬间。

产品包装的背面则是产品的一些功能和特色介绍,其最大的读写速度分别为100MB/s和85MB/s,并支持4K视频的拍摄,并具备耐受-25℃~85℃极端温度、防X射线、防水、5米抗摔等特性,可满足摄影爱好者在各种恶劣环境中高清拍摄的使用要求。

铠侠 EXCERIA PLUS 存储卡为标准的SD卡规格,三围是32*24*2.1mm,重量约为2克,壳体是经典的白红配色,让人印象深刻,而左边的黄色开关,则用于数据读写锁定,需要的时候可以拨下来。

这张存储卡的背面则是全白配色,上面印有一些序列号之类的信息,产地则是日本,通过了CE认证。

这次我们手上的是256G版本,可以存储500万像素的图片约162710张;1800万像素的图片约38510涨;高清视频(12Mbps)约2620分钟;4K(100Mbps)约314分钟,让你无须拍摄担心存储空间不够使用。此外,还拥有32G、64G和128G三个版本,消费者可以根据自己的需求选择适合自己的容量。

这款存储卡采用的是铠侠原厂的BiCS Flash 3D闪存颗粒,品质有保障,这也是目前铠侠品牌立足之根本了。

高速读写,4K@60p高码率随心录

作为一张SD卡,最常用的场合就是相机了,不过现今相机拍摄时产生的数据读写速度也不是一般SD卡能承受的,铠侠EXCERIA PLUS经过我们测试,无论是使用EOS R高速连拍3030万像素照片,还是使用富士XT-3拍摄4K@60P 高码率视频,它都能非常顺畅的完成任务。

在EOS R上,SD卡存取速度的快慢会影响高速连拍的速度,我们实际测试的连拍效果是非常给力的,不过在文章中就无法展现出高速连拍的效果了,我们就选择拍摄4K@60P视频来体现存储卡的速度。

富士XT-3要开启4K@60P的条件比较苛刻,只要存储卡没有达到标准,选项是灰色不可选取状态。而铠侠EXCERIA PLUS开启富士XT-3的4K@60P拍摄模式是没有问题的,且可以选择最高码率200Mbps。

实际拍摄的效果如动图,非常流畅。

性能小测:连续读写稳定够用

接下来就是速度测试环节,我们首先使用了3款常用存储产品测试软件来测出它的理论读写速度,后面也会加入实际传输测试。

首先是Crystal Disk Mark测试,在1G文件的测试中,这款存储卡的写入速度为86.41MB/s,读取速度为97.74MB/s。

在ATTO Disk Benchmark测试中,可以根据不同大小的数据包来检验这两张内存卡在不同文件大小下的读写性能。铠侠 EXCERIA PLUS系列 存储卡 256G版本最高写入速度达到93.43MB/s,最大读取速度为86.66MB/s,基本达到了官方的数据(官方测试以1mb=1000kb进行换算)。同时,从测试我们可以发现,铠侠这款SD卡在64KB到4MB之间时,读写性能是最优的。这也可以理解为大文件顺序读写的范围,在读写如视频,图片这种体积较大的文件时能保证较高的速度。

然后在HD Tune Pro下的文件基准测试,该模式下分别通过真实写入文件后再读取文件的方式进行测试,能很好地模拟存储卡的实际工作状态和真实传输速度。 这张存储卡的定位是主打高性能,为了测试这张存储卡在长时间连续读写场景使用下有何表现,我们设定了20G的文件长度进行测试,传输速度一直稳定在85MB/s左右,整体表现非常稳定。

最后是实际传输测试环节,通过拷贝13GB大小的MP4格式视频文件来测试这款存储卡的传输速度,这张铠侠 EXCERIA PLUS系列 存储卡的写入速度基本是稳定在84MB/s左右,和上面的测试结果比较接近,稳定性十分出色。

PConline 评测室总结:好用的大容量高速卡

铠侠 EXCERIA PLUS系列 存储卡主打高性能,最大读写速度分别达到了97.74MB/s,86.410MB/s,性能比自家的持久存储系列还要略胜一筹,再加上原厂的颗粒加持,让这款存储卡能够拥有出色的传输稳定性,可以说是继承了东芝存储一直以来的高品质。此外,能够耐受-25℃~85℃极端温度、防X射线、防水、5米抗摔等特性,非常适合各位“快枪手”在各种环境下拍摄出卓越质量的照片和视频。

免责声明:本文由用户上传,如有侵权请联系删除!