IOは、それが何を意味して多重化?(復刻版)

転送:https://www.zhihu.com/question/32163005

これはどういう意味多重1 IO? - Luozhiゆうの答えは - 知っているほとんどhttps://www.zhihu.com/question/32163005/answer/55772739

これは明らかに言って非常に良いです。

インバウンド、アウトバウンド、および一部の便を含め、あなたの空港のルートを管理するために必要なのは、ターマック待機を配置する必要があり、一部の便は、ゲートに搭乗する乗客を選択する必要があり、あなたが空港の航空管制していると仮定します。

あなたはどのように行うのでしょうか?

最も簡単な方法は、あなたが次の空港、プロセス監視にハンドオーバーするまで、管制官の多数を募集し、その後、出発、ルートの監視を、ピックアップ予選、インバウンドから、一人一人に飛行機を凝視に行くです。

そこで問題が発生します:

  • すぐにトラフィック少し忙しい、管制官が高額の内側に集まっている航空管制タワーを見つけるだろう、新しい管制官はスクイズで来ていませんでした。
  • 管制官の間の調整の必要性が、幸いにも1、2、個々の時間に家の中に、Jishihaoren後、基本的には野菜市場になります。
  • 航空管制官は、多くの場合、次の時間のフライトの出発後のような離陸ディスプレイなどの一般的なもの、の一部を更新する必要があり、最終的にあなたはすべての人の時間が最後のグラブにこれらのリソースを費やしていることを見つけるために驚かれることでしょう。

 

実際には航空機のありふれたものの数十は、彼らはそれをどのように行う、当社の航空管制チューブながら?
彼らはこの事を使用します

運航票と呼ばれるこの事は。各ブロックは、国家を代表して、飛行、異なるスロットを表し、その後、管制官は、そのようなブロックのセット(飛行のグループ)、および彼の仕事を管理することができ、それは、フライト情報を持つことです新しいアップデート、トラフに、別のブロックに対応します。

 

この事はまだちょうど電子のみとなって、ああ排除されていません。

突然たくさんの高効率化のすべて、航空管制タワーはルートが複数回に数回前の方法することができスケジュールすることができますということではありません。

ソックス(I / Oストリーム)として使用すると、すべての航空会社を置く場合は、ATCサーバソックス管理コードワードとして。

第一の方法は、最も伝統的なマルチプロセスの同時実行モデル(新しいプロセス管理を割り当てられる各新しいI / Oストリームに来る。)であり、
第2の方法はトラックを記録することにより、I / O多重化(シングルスレッドでありますI / Oは、複数のストリームを管理するために、各I / Oストリーム(私達の靴下)の状態、および。)

実際には、「I / Oマルチプレクサ」これが理由のピットの父は中国の内部に理解することが非常に困難をこの概念を翻訳することができます。:基本的にこのチャートアウトになり、あなたは何を意味するの多重化を検索する場合I / Oを多重化と呼ばれる、I / Oは、実際には、英語で多重いわゆる

あなたは、複数のプロセスやI / Oマルチプレクサを使用するかどうかだから、ほとんどの人が直接、実際には、上記の回答のいくつかを含め、「ネットワークケーブル、複数の靴下の再利用」の概念に関連付けられている、ネットワーク回線は一つだけ良いですカッティング。靴下は、この関数は、カーネルドライバ層+に実装され、ケーブルの複数の多重化。

重要なのリピート:I / Oを管理するために、(タワーファイト進捗ストリップ溝内の空のチューブに相当)多重化手段内で実際に記録することにより、単一のスレッドがそれぞれソックス(I / Oストリーム)の状態を追跡していることを多重化しますI / O複数のストリーム。本発明は、サーバーのスループットを向上させることができるだけである理由。

 

理解するためのマップを見て、それが良い一口に聞こえるではありません。

 


DIPの方法により、同時に複数のIを送信するために切り替わり、同じスレッドで/ Oストリーム(EEは学んだ今義政が立ち上がることができます人々は厳しく、これは「多重時分割」と呼ばれている、と述べました)。

 

何を、あなたは「のような要求の受信処理要求が到着し、nginxの使用のepoll」を知ってもらう、この図を理解した上で、より読んでいません。リマインダーの下では、入ってくるリンクの多くを持ってngnix、彼らはそれを監視する必要がありますファイルディスクリプタ、その後、ダイヤルスイッチのように、のような、誰が誰のデータに割り当てられます、そしてハンドルに適切なコードを呼び出します。

------------------------------------------
今後、この基本的な考え方を理解し、他の良い説明に。

選択し、特定の実装の世論調査、I / Oは、多重のepollすべて、3人の幽霊がある理由が存在し、実際に、彼らはシーケンシャルで表示されます。

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在不在池里面。

おすすめ

転載: www.cnblogs.com/raohuabing/p/12216962.html