マルチクライアント処理と反復型サーバの限界 マルチクライアント処理と反復型サーバ の限界 TCPエコーサーバの実際のスループット 反復型サーバの限界 反復型サーバの問題点 力ずくの(面倒な問題を内在する)解決策 力ずくの解決策に内在する、面倒な問題 シンプル、且つ、スマートな解決策 スマートな解決策でのサーバの構造 サーバ処理多重化のためのfork()システムコール プロセスの概念 プログラムの実行とプロセス 親と子の区別:fork()の返り値 fork()型サーバの構造 マルチクライアント処理と反復型サーバの限界 TCPエコーサーバの実際のスループット サーバ サービス 処理 listen() 一時に唯一のサービス 逐次的な処理 accept() TCP 複数のクライアントから 同時にアクセスを受ける クライアント クライアント クライアント クライアント クライアント マルチクライアント処理と反復型サーバの限界 反復型サーバの限界 サーバー サービス処理 サーバの構造的問題 複数のクライアントから 同時にアクセスを受ける が、一時に唯一のサー ビスしか処理できない 集中! クライアント クライアント クライアント クライアント クライアント クライアント マルチクライアント処理と反復型サーバの限界 反復型サーバの問題点 一つのクライアントに対応している間は、他のク ライアントに対応できない! 複数のクライアントが一度にアクセスした場合を考慮 しなければいけない どこがネックか? accept()を多重化して実行できると良い? 実際の処理を多重化して実行できると良い? マルチクライアント処理と反復型サーバの限界 力ずくの(面倒な問題を内在する)解決策 単純に沢山のソケットを扱ってみる サーバ listen() サービス 処理 accept() サービス 処理 サービス 処理 accept() accept() TCP クライアント クライアント クライアント マルチクライアント処理と反復型サーバの限界 力ずくの解決策に内在する、面倒な問題 たくさんのソケットを扱うと,サーバのプログラム が、極度に複雑化する いちいちソケットを検査するのが極めて面倒 どのクライアントのサービス処理に、どれだけ時間が かけられるかをいちいち判別して順序付けるのは、 原理的に不可能に近い 沢山のクライアントが接続してきた場合、沢山の ソケットオブジェクトを、サーバの責任で一元管 理するのは極めて困難 マルチクライアント処理と反復型サーバの限界 シンプル、且つ、スマートな解決策 サーバ自身が自分の分身を作ればいい! 仕事は全部,分身にまかる 親の仕事は,コネクションがきたときに分身を作 ることだけ 親(仕事分配)プロセス 子(仕事遂行)プロセス 子(仕事遂行)プロセス t マルチクライアント処理と反復型サーバの限界 スマートな解決策でのサーバの構造 accept()を多重化して実行 サーバ 親(仕事分配) プロセス listen() accept() サービス サービス 処理 サービス 処理 サービス 処理 処理 サーバの 分身(仕事遂行) 子プロセス 実際の処理を多重化 して実行 TCP クライアント クライアント クライアント クライアント クライアント クライアント マルチクライアント処理と反復型サーバの限界 サーバ処理多重化のための fork()システムコール pid = fork(); 自分とまったく同じ複製プロセスを作るシステ ムコール 自分がコピーかどうかの判別 0が帰ってきたら自分は子プロセス 正の整数が帰ってきたら自分はfork()を呼び出し た親プロセス -1は失敗 マルチクライアント処理と反復型サーバの限界 プロセスの概念 仕事=アプリケーション=コマンド=プログラム アプリケーションの実行 プログラムの実行イメージをプロセスとして実行 プロセス=仕事のためにOSが計算資源を割り 当てる粒度 プロセス プログラムの実行イメージに 、 OSが計算資源(メモリ・計 算時間・ソケットオブジェクト ・その他)を割り当てる プログラムの 実行イメージ マルチクライアント処理と反復型サーバの限界 プログラムの実行とプロセス プログラム 実行イメージ プログラム main(int argc, char *argv) { struct sockaddr_in me, peer; ……. if(pid = fork()) == 0) { child process. } else if(pid > 0) { parenet process. } else { error process. } } 実行 親プロセス main(int argc, char *argv) { struct sockaddr_in me, peer; ……. if(pid = fork()) == 0) { child process. } else if(pid > 0) { parenet process. } else { error process. } } プログラム コピー 生成 main(int argc, char *argv) { struct sockaddr_in me, peer; ……. if(pid = fork()) == 0) { child process. } else if(pid > 0) { parenet process. } else { error process. } } 生成 fork() OS 子プロセス マルチクライアント処理と反復型サーバの限界 親と子の区別:fork()の返り値 int parent; parent = fork(); 親側 if(parent > 0){ 親の処理; } 子側 else if(parent == 0){ 子の処理; } マルチクライアント処理と反復型サーバの限界 fork()型サーバの構造 accept()を多重化して実行 サーバ 親(仕事分配) プロセス listen() accept() サービス サービス 処理 サービス 処理 サービス 処理 処理 fork() サーバの 分身(仕事遂行) 子プロセス 実際の処理を 多重化して実行 TCP クライアント クライアント クライアント クライアント クライアント クライアント
© Copyright 2024 ExpyDoc