同期/非同期、ブロッキング/非ブロッキング、Linux IOモデルを理解する方法は、/ poll / epollを選択します

関連するビデオ分析

epollのネットワークモデル(redis、memcachedからnginxまで)
は、Linuxサーバーのパフォーマンス最適化の非同期原理を実行し、ユーザーモードネットワークプロトコルスタックの手書きを実現し
ます。これにより、ネットワークスキルが即座に向上します。

序文

強迫性障害は、説明を与えずにこの非常に状況的な概念を容認することはできません。同期/非同期、ブロッキング/ノンブロッキング、ブロッキングIO /ノンブロッキングIO /同期IO /非同期IO / IO多重化(IO多重化)、これらの選択/ポーリング/エポールこの概念は長い間私を悩ませてきました。この段階での理解は以下のとおりです。

同期/非同期およびブロッキング/非ブロッキングの理解

スレッドは、プログラム実行における単一の順次制御フローであり、プログラム実行フローの最小単位であり、プロセッサーのスケジューリングとディスパッチの基本単位です。スレッドを使用してプログラムフローを実行し、同期と非同期、ブロッキングと非ブロッキングを理解します。同期および非同期は、フロー実行プロセスが外部呼び出しの結果を待機する必要があるかどうかに焦点を当て、非ブロックのブロックは、フロー自体に対する外部呼び出しの影響に焦点を当てます。

同期および非同期

スレッドの実行中に外部呼び出しが生成されます。スレッドフローを続行するために呼び出しが戻るのを待つ必要がある場合、それは同期と呼ばれます。結果を待たずにスレッドフローを実行し続けることができる状況リターンは非同期と呼ばれます。
区別:スレッドフローダウンの実行は、システムコールの結果を待つ必要はありません。

ブロッキングと非ブロッキング

スレッドの実行中、外部呼び出しが生成された後、スレッドフローは「ブロック」されますか?「ブロック」はブロックに対応し、その逆も同様です。

Linuxの5つのIOモデル

前のセクションでの同期/非同期、ブロッキング/非ブロッキングの説明は、それらを区別できるとしか言えません。コンピュータの分野ではなく、生活の中で、真実は似ています。ただし、コンピュータの一部の専門用語は、以下で説明するLinux IOモデルなど、特別なコンテキストで表示する必要があります。同期/非同期およびブロッキング非ブロッキングという言葉ではなく、モデル自体を理解することをお勧めします。非ブロッキングモデルにもブロッキング部分があります。同期IOと非同期IOの違いは、IO操作中にプロセスがブロックされるかどうかです。
以下のモデルの説明の最終的なソースは次のとおりです
。RichardStevensによる「UNIX®️NetworkProgrammingVolume1、Third Edition:The Sockets Networking」、セクション6.2「I / Oモデル」
同期I / O操作により、要求プロセスがブロックされます。そのI / O操作が完了するまで;
非同期I / O操作によって、要求プロセスがブロックされることはありません。

同期IOモデル

IO動作のブロッキングから判断すると、5つのIOモデルのうち4つは同期IOに属しており、ブロッキングIOモデル、非ブロッキングIOモデル、IO多重化モデル、および信号駆動型IOモデルです。

IOのブロック

ブロッキングIOはソケットのデフォルト設定です。そのモデルを次の図に示します。プログラムはrecvfromを呼び出してシステムコールを生成します。カーネルが呼び出し要求を受信した後、2つのステップがあります。1つ目はデータを待つことです。 2つ目は、カーネルからデータを転送することです。スペースがユーザースペースにコピーされ、OKが返されます。ユーザースペースは、システムコールが戻るまで、プログラムフローの実行を続行しません。
ここに画像の説明を挿入

ノンブロッキングIO

ソケットのノンブロッキングIOモデルは別途設定する必要があります。ノンブロッキングIOモデルを以下に示します。カーネルがシステムコールを受信した後、データがすぐにエラーを返す準備ができていない場合、ユーザープロセスは、エラーを受信した後、データの準備ができてユーザースペースにコピーされるまで、システムコールを生成し続けます。
ここに画像の説明を挿入
[記事のメリット] C / C ++ Linuxサーバーアーキテクトの学習資料とグループ812855908(C / C ++、Linux、golangテクノロジー、Nginx、ZeroMQ、MySQL、Redis、fastdfs、MongoDB、ZK、ストリーミングメディア、CDN、P2P、K8S、 Docker、TCP / IP、coroutine、DPDK、ffmpegなど)
ここに画像の説明を挿入

IO多重化

select / poll / epollは、IO多重化モデルに対応します。複数のソケットを監視できるという利点があります。モデル図を以下に示します。ユーザープロセスはselectを呼び出して、システムコールを生成します。カーネルは、selectが担当するすべてのソケットを監視します。ソケットデータの準備ができると、カーネルは戻り、ユーザーはrecvfromに移動して、システムコールを生成します。カーネルスペースからユーザースペースへ。
ここに画像の説明を挿入

信号駆動型IO

ユーザープログラムはシグナルハンドラーを登録し、次のことを続行します。カーネルデータの準備ができると、シグナルを送信し、プログラムはrecvfromを呼び出してシステムコールを実行し、データをカーネル空間からにコピーします。ユーザースペース。
ここに画像の説明を挿入

非同期I / Oモデル

IO動作の非ブロッキングから判断すると、5つのIOモデルの中で非同期IOのみが使用可能です。

非同期IO

非同期IOモデルは次のとおりです。Aio_readはシステムコールを生成します。データの準備ができたら、カーネルはデータをカーネルスペースからユーザースペースにコピーし、読み取りデータの成功を通知する信号を返します。プログラムがaio_readを呼び出した後、シグナルを受信するまで他の部分を実行し続けます。ハンドラーを呼び出して処理します。
ここに画像の説明を挿入

モデル比較

カーネルには2つのプロセスがあり、データの準備が整うのを待って、データをユーザースペースにコピーします。ユーザープログラムのブロックには、通常、選択ブロックとソケットIOブロックの2つの状況があります。5のIOモデルの比較は次のとおりです。

ここに画像の説明を挿入

select / poll / epoll

Select / poll / epollは、複数のファイル記述子fdを同時に監視でき、fdの読み取りおよび書き込み操作が完了すると、これらのfdを返します。これは、fdの準備ができているかどうかを照会するIO多重化モデルのシステムコールに対応できます。データ用。

選択する

int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds,struct timeval *timeout);

typedef struct {
    
    
    unsigned long *in, *out, *ex;
    unsigned long *res_in, *res_out, *res_ex;
} fd_set_bits;

Selectは、ユーザーレイヤーの特定の構造を使用して、監視対象のfdと監視状態を識別します。各fdは1ビットで表され、1はファイルが監視されていることを意味し、0は監視されていないことを意味します。in、out、およびexが指すビット配列は、対応する読み取り、書き込み、および異常なファイル記述子を表します。res_in、res_out、res_exが指すビット配列は、対応する読み取り、書き込み、および異常なファイル記述子の検出結果を表します。

1.この構造がカーネルレイヤーにコピーされ
ます。2。すべてのfdに対してコールバック関数__pollwaitを登録します。3。fd
のpollメソッドを呼び出して、FD_SESIZET全体のすべてのfdをトラバースし、監視する必要があるかどうかを確認します。 fdの監視が感じられる関心のあること(ファイルの読み取りおよび書き込み操作が完了または異常である場合は、ユーザーモードのプリセット設定を参照)について、pollメソッドは読み取りおよび書き込み操作の準備ができているかどうかを説明するマスクを返し、に値を割り当てます。マスクマスクに応じたfd_set。poll-> poll_wait-> __ pollwaitは、現在のプロセスを、対応するファイルのiノード内のfdの待機キューにハングアップさせます。
4.トラバーサルのラウンドが失敗した場合、タイムアウトになるか、デバイスドライバーが自身のリソースの読み取りと書き込みを行った後、待機キューからウェイクアップするまで一時停止され、新しいラウンドのトラバーサルが実行されます。
5. fd_setをカーネルスペースからユーザースペースにコピーし、各待機キューからプロセスを削除します。

投票

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

struct pollfd {
    
    
    int fd;
    short events;
    short revents;
};

pollの実装メカニズムはselectの実装メカニズムと似ていますが、pollの使用では、ユーザーモードが監視する必要のあるfdに関する情報を直接提供し、pollfd構造が監視対象のfdとそのステータスを記録する点が異なります。

struct poll_list {
    
    
struct poll_list *next;
    int len;
    struct pollfd entries[0];
};

さらに、pollはpoll_list構造を使用して、監視対象のfdを記録します。各poll_listノードにはpollfd配列が含まれます。パラメーターがカーネルにコピーされた後、poll_listがトラバースされます。つまり、pollfd配列がトラバースされます。selectと同様に、すべてfdがトラバースされます。

epoll

int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

Epollは、プロセスを1つのepoll_create、複数のepoll_ctrl、および1つのepoll_waitを含む一連のシステムコールに絞り込みます。カーネルは、epoll操作用のファイルシステム「eventpollfs」を追加します。監視対象の各fdには、対応するeventpollfsファイルシステムiノードノードがあります。主な情報はeventpoll構造に格納され、監視対象ファイルは重要です。情報はに格納されます。エピテム構造。epoll_createとepoll_ctrlを実行すると、ユーザー状態情報がカーネル状態に保存されます。その後epoll_waitが繰り返し呼び出されても、select / poll、scan fdなどのパラメーターを繰り返しコピーしたり、現在のプロセスを待機キューに繰り返し入れたり出したりすることはありません。 。

epoll_create

epoll_create()の機能は、eventpollfsファイルシステムのiノードノードを作成することです。主な情報はeventpoll構造に格納されます。Eventpollは、eventpollfsファイルシステムのiノードの重要な情報を記録します。メンバーrbrは、監視対象のすべての記述子を保存します。 epollファイルノードによる。、編成方法は赤黒の木であり、監視対象ファイルの重要な情報はエピテム構造に格納されます。

epoll_ctl

Epoll_ctlは、一連の操作を実装します。ep_find()を呼び出して、eventpollの赤黒木からエピテム構造を取得し、opパラメーターに従ってさまざまな操作を選択します。opがEPOLL_CTL_ADDの場合、一般にeventpollの赤黒木にエピテムが見つからないため、ep_insertを呼び出してエピテム構造を作成し、対応する赤黒木に挿入します。

init_poll_funcptr(&epq.pt, ep_ptable_queue_proc);
…
revents = tfile->f_op->poll(tfile, &epq.pt);

次に、ep_insertはinit_poll_funcptrを呼び出して、コールバック関数ep_ptable_queue_procを登録します。これは、f_op-> pollが呼び出されたときに実行されます。Ep_ptable_queue_proc関数は、epoll待機キューノードepoll_entryを割り当てます。一方では、ファイル操作待機キューにハングアップし、他方では、エピテムキューにハングアップします。さらに、待機キューコールバック関数ep_poll_callbackも登録し、操作を完了して現在の待機プロセスをウェイクアップする前にep_poll_callbackを呼び出し、epitemをeventpollの完了キューに入れてから、待機プロセスをウェイクアップします。

epoll_waite

epoll_waitの仕事は、ファイル操作が完了して戻るのを待つことです。その本体はep_poll()です。この関数は、eventpollに完了したイベントがあるかどうかを確認し、ある場合は結果を返します。そうでない場合は、schedule_timeout()を呼び出して、プロセスが再びウェイクアップされるかタイムアウトになるまでスリープ状態になります。

比較

select / pollの弱点は、fdをポーリングしてトラバースする必要があることです。これは、fdモニタリングが多い場合はコストがかかりますが、epollはコールバック関数に依存し、アクティブなfdが多すぎる場合はオーバーヘッドが大きくなります。

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_40989769/article/details/112475394