LinuxのNIOシリーズ(4月4日)を選択し、ポーリング、ファイルディスクリプタのコントラスト

LinuxのNIOシリーズ(4月4日)を選択し、ポーリング、ファイルディスクリプタのコントラスト

ネッティーシリーズカタログ(https://www.cnblogs.com/binarylei/p/10117436.html

今すぐ投票/ファイルディスクリプタは実装固有のI / Oの多重化され/選択し、今存在し、実際に、彼らはまた、異なる歴史的時期の産物である理由

  • BSDの実装内で1984年に現れる選択
  • それは長いを選択し、神が存在する単純として、1997年に14年後に、投票を達成することができた、実際には、あまりにも長い間待っているため、効率ではなく、その時代のハードウェアが弱すぎる、1,000以上のリンクサーバープロセスであります時間のニーズの期間が満たされています
  • 2002年、偉大な神ダヴィデLibenziは、ファイルディスクリプタを実現しました

、APIの比較

1.1 APIを選択

int select(int maxfdp, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeval *timeout);
int FD_ZERO(int fd, fd_set *fdset);     // 一个 fd_set 类型变量的所有位都设为 0
int FD_CLR(int fd, fd_set *fdset);      // 清除某个位时可以使用
int FD_SET(int fd, fd_set *fd_set);     // 设置变量的某个位置位
int FD_ISSET(int fd, fd_set *fdset);    // 测试某个位是否被置位

1つのselect()のメカニズムを提供するデータ構造のFD_SETが、実際には配列のロングタイプです(コールを選択したときに、(このリンクは、独自の完全なを必要とする)配列の各要素は、接触を確立するためにファイルハンドルで開くことができ、 )、カーネルによってIO状態をかかるコンテンツFD_SETは、それによって選択の実行()、またはプロセスソケット可読ファイルを通知します。

選択メカニズムを発行

  1. select呼び出しは、あなたがFD_SETコレクションが大きい場合には、カーネルモードために、ユーザーモードからFD_SETコレクションをコピーする必要があるたびに、これはまた、偉大なコストであります
  2. FD_SETコレクションが大きい場合には、同時に、各コールのfd_setはカーネルに渡された横断するために、すべての必要性を選択し、その後、これも素晴らしいコストであります
  3. パフォーマンスデータのコピーへのダメージを軽減するために監視されているFD_SETカーネル・セット・サイズをもたらした制限を行う(デフォルトは1024です)

1.2ポーリングAPI

int poll(struct pollfd *fds, nfds_t nfds, int timeout);
struct pollfd {
    int fd;         // 文件描述符
    short events;   // 感兴趣的事件
    short revents;  // 实际发生的事件
};

ポーリングと記述子の複数の管理ではなく、多くの異なる性質で選択するために、同様の機構を選択し、ポーリング、処理記述子状態に応じてであるが、ファイル記述子のポーリング制限のない最大数はありません。言い換えれば、世論調査では唯一のパフォーマンスのオーバーヘッドの問題1と2の問題を解決しない、上記の問題を解決する3。

1.3のepoll API

// 函数创建一个 epoll 句柄,实际上是一棵红黑树
int epoll_create(int size);
// 函数注册要监听的事件类型,op 表示红黑树进行增删改
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
// 函数等待事件的就绪,成功时返回就绪的事件数目,调用失败时返回 -1,等待超时返回 0
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

正式Linux2.6カーネルで提案されているファイルディスクリプタが、されるイベント駆動型I / Oモードに基づいて、それが選択し、ファイルディスクリプタの記述に相対的である数に制限はありません、複数のディスクリプタを管理するためのファイル記述子を使用し、ユーザーへの関心のファイルを記述するそのようフーイベントは、ユーザ空間とカーネル空間でイベントテーブルのカーネルにコピーを1つだけ保存されました。

第二に、要約

I / O多重化I / Oプログラミングプロセス、それはアクセス要求がマルチスレッドまたはI / O多重化を使用して処理することができる複数のクライアントを処理する必要がある場合。I / O多重化システムは、シングルスレッドのクライアント要求が複数同時にケースを扱うことができるように、同じことが、選択ブロックに多重化I / O輻輳複数の。伝統的なマルチスレッド/マルチプロセスモデル比では、I / Oの多重化の最大の利点は、小規模なシステムのオーバーヘッドで、システムは、還元、これらの保守プロセスとスレッドを実行する必要はありません、新たな追加プロセスやスレッドを作成する必要はありません。システムリソースを節約し、システムのメンテナンス・アクティビティ、次のように、I / Oの多重化の主なシナリオは以下のとおりです。

  • 複数のサーバは、状態または接続状態をリスニングでソケットの複数を処理する必要が
  • ソケットサーバは、さまざまなネットワークプロトコルを処理する必要があります。

現在選択ポーリングとネットワークイベント通知を利用するのに長い時間のために、Linuxネットワークプログラミングで、I / Oの多重化システムコールを選択し、PSELECT、投票のepollをサポートしています、しかし、固有の欠陥のいくつかは、鉛を選択しますその使用が大幅に制限され、最終的には新しいカーネルのバージョン、最終的な選択のファイルディスクリプタでのLinuxを選択するための代替手段を見つけなければならなかったされています。原理のepollと選択の欠点を克服するために、より多くの同様の選択は、ファイルディスクリプタは大幅な改善をたくさん作っ、以下に要約されています。

2.1ソケットディスクリプタ(FD)無制限(唯一のオペレーティングシステムハンドルによって制限される最大ファイル)を開くためのプロセスをサポート

単一の最大欠陥が開放されているFDのプロセスで選択するFD_SETSIZEセットから成る一定の限界であり、デフォルト値は、1024です。大規模なサーバーのTCPコネクションの数万人をサポートする必要がある人のために明らかに少なすぎます。このマクロは、カーネルを変更して再コンパイルすることを選択できますが、これはネットワーク効率をダウンさせるでしょう。私たちは、マルチプロセスプログラム(伝統的なApacheのプログラム)を選択することで、この問題を解決することができますが、Linuxのコストに作成するプロセスは比較的小さいものの、それでも無視することはできません。付加的な性能損失をもたらすない共有メモリ、データ同期ソケット通信または他の手段の必要性がないため他に、Javaのための面倒なプロセス間のデータ交換は、プログラムが複雑化し、そうでありません完璧なソリューションのようなもの。幸いなことに、ファイルディスクリプタは、この制限はありません、FD上限は、オペレーティングシステムのファイルハンドルをサポートしていることを最大の、1024よりもはるかに大きい数字です。例えば、1GBのRAMを持つマシン上で約100 000は、特定の値は、猫PROC / SYSの/ fsの/ファイル-MAXビュー、通常、比較的大規模なシステムとメモリの値との関係とすることができるハンドルです。

# (所有进程)当前计算机所能打开的最大文件个数。受硬件影响,这个值可以改(通过limits.conf)
cat /proc/sys/fs/file-max

# (单个进程)查看一个进程可以打开的socket描述符上限。缺省为1024
ulimit -a 
# 修改为默认的最大文件个数。【注销用户,使其生效】
ulimit -n 2000

# soft软限制 hard硬限制。所谓软限制是可以用命令的方式修改该上限值,但不能大于硬限制
vi /etc/security/limits.conf
* soft nofile 3000      # 设置默认值。可直接使用命令修改
* hard nofile 20000     # 最大上限值

2.2 I / O効率直線FDの減少の数に増加するようではありません

伝統的な選択/世論調査では、別の致命的な弱点は、それはあなたが、ネットワークの遅延のために、ソケットの偉大なセットを持っているか、リンクがいずれかの時点でアイドル状態のときにソケットのほんの一部が「アクティブ」であるということですが、/投票それぞれを選択します呼び出しが減少し、効率リニア・プレゼンテーションで、その結果、線形のセット全体をスキャンします。この問題を持っていないファイルディスクリプタ、それだけであろう「アクティブ」ソケットが動作-これはカーネルの実装、ファイルディスクリプタfdは上記コールバック関数の各々に従って実装されているためです。だから、唯一の「アクティブ」ソケットバイオはありません、コールバック関数を呼び出すためのイニシアチブをとるソケット他のアイドル状態になります。この時点で、ファイルディスクリプタは擬似AIOを実装しています。コントラストとのepollパフォーマンスのベンチマークテストがあることを示す選択:ソケットの全てがアクティブ状態にある場合 - 例えば、高速LAN環境を選択/世論調査はるかに高い効率よりも良いのepoll;逆に、過度のepoll_ctlの使用だけでなく、効率を比較すると、若干低下が、アイドル状態の接続がシミュレートされたWAN環境を使用することにより、これまでのepoll上記の効率は/ポーリング選択することになります。

2.3のmmap加速カーネルとユーザー空間メッセージング

選択、投票やファイルディスクリプタのカーネルは不要なメモリコピーを回避する方法、ユーザ空間にFDメッセージ通知する必要があるかどうかは、達成するために、メモリの同じ部分にmmapカーネルとユーザースペースで非常に重要な、ファイルディスクリプタです。

2.4のepoll APIより簡単に

epollディスクリプタの作成など、イベントはその上のepollディスクリプタを閉じて、するために、ブロック待機を聞いて、イベントリスナーを追加します。

それだけではない選択/世論調査の欠点を克服するためのepollするために使用される方法は、ファイルディスクリプタはちょうどLinuxの実装であることに留意すべきです。そこFreeBSDのkqueueのであり、及びDEV /世論調査では、使用の難易度の低い順に、最も古いSolarisのプログラムです。kqueueのは、それが実際にはかなり豊富な機能を備えたカーネルイベントキューFreeBSDの最愛の人だが、それはようにだけ選択/世論調査をアップグレードされていない、と複数のイベント信号を処理することができ、ディレクトリ構造を変更、プロセスと。たkqueueはエッジトリガです。/ dev /世論調査のSolarisは、最初に登場し、高性能APIのこのシリーズの製品です。カーネルは、特殊なデバイスファイルは/ dev /投票を提供するアプリケーションは、取得した操作のfd_setにファイルハンドルを開き、ポーリングを書き込むことによって、それを変更、特定のioctlは選択置き換えるために呼び出します。しかし、それ以前の年のそれが現れ、そうは/ dev /ポール・インタフェースは、プリミティブです。

表1:選択/世論調査/ epollを差

比較します 選択 投票 epollを
動作モード トラバーサル トラバーサル コールバック
基本となる実装 配列 リスト 赤、黒の木
IO効率 各コールを横切る線形、
時間計算量はO(N)
各コールを横切る線形、
時間計算量はO(N)

イベント通知の方法は、準備ができfdはいつでも、
システム登録したコールバック関数が呼び出されます、
準備が整いますreadyListに内側に、FD
Oの時間複雑(1)
最大接続数| 1024 |無制限|無制限
FDコピー|毎回、select呼び出し
モードをカーネルにユーザーモードからコレクションコピーをfdに必要|各コールの世論調査では、
epoll_ctlを呼び出すときに、カーネルにコピーして保存|カーネルモードために、ユーザーモードからコレクションコピーをfdに必要
コピーしないイベントがepoll_wait各後

概要:のepoll Linuxは大規模ネットワーク、現在の並行プログラム開発のための好適なモデルです。選択して投票よりもほとんどの場合性能で。人気の高性能Webサーバnginxの関係者は提供効率的なネットワークソケットのepollのポーリングサービスに依存しています。しかし、同時接続の場合には高くはないが、マルチスレッド+ブロッキングI / O性能がより良い方法であってもよいです。

参考:

  1. IO多重3つのメカニズムを選択し、投票、ファイルディスクリプタ

毎日少しを記録する意向。おそらく、内容は重要ではありませんが、習慣は非常に重要です!

おすすめ

転載: www.cnblogs.com/binarylei/p/11130079.html