muduoの主要クラスの実現構想を整理する

2480 ワード

文書ディレクトリ

  • TcpConnection
  • Buffer
  • Log
  • ThreadPool
  • タイマ
  • 同時接続を制限
  • TcpConnection


    宣言サイクルをスマートポインタで制御する唯一のクラスは、いつ終わるかを長い間探していました.TcpServerにはConnを保存するスマートポインタがあるので、参照カウントはずっと1です.
    エンドクローズのメッセージを受け取ると、handleEvent()の中にあるので、直接解析することはできませんので、TcpConnection::handleClose()の中にshared_を使いました.from_this()は参照カウントを一時的に1を加算し,TcopConnection::connectDestory()関数をタスクとしてloopを実行させることで,loopがこの関数を実行すると楽しく解析できる.

    Buffer


    このbufferは本当に先生にdissされて久しい..データ構造といえばvectorで、3つの部分に分かれています.第1部は8バイトで、残された頭部として、便利になってから前にbuflenなどを付けます.第2部はreadable部で、データは両端から来てからここに置いて、固定サイズがなくて、大きすぎると後ろの部分の空間を占有して、更に大きいvectorは自動的に拡張して、しかし自動的に縮小しません.第3の部分は第2の部分の終わりに続いてwriteable部分としてバッファを送信することを意味し,同様に自動的に拡大するが自動的に縮小しない.
    1つの問題は、各接続に大きなBufferが使用されている場合、1つ以上のメモリを接続すると大きくなりますが、これらのBufferの使用率は大きくありません.したがってmuduoは、スタックに空間を割り当て、readv()で読み出すソリューションを与えた.では問題ですが、このスタックスペースは誰のスタックですか?答えは、スタックはBuffer::readFD()の中にあり、関数が終わると破棄されます.システム呼び出しを減らすことを目的とし、一度に読むデータが多ければ多いほど良い.複数回のreadシステム呼び出しを呼び出す時間をスタック空間とappendデータを開く時間に置き換えると、read時間が長くなるとより速くなります.

    Log


    ログは、デュアルバッファ技術を使って、2つのbuffer AとBを用意することを考えています.フロントエンドはAにデータを书き、Aが満タンになったらAとBを交换し、バックエンドは満タンになったAをハードディスクに书き戻し、このように缲り返します.muduoのほうは4元用意されていますが、足りなければ臨時にスペースを申請することもできます.プログラムクラッシュ問題解決策は、メモリ内のログメッセージにcookie/centeryがあり、その値は関数のアドレスであり、gdb findコマンドで表示することができ、クラッシュ時のログメッセージを見ることができます.(まだよくわかりませんが、後で見てから補充して、また補充を思い出したら)

    ThreadPool


    これが正常なスレッドプールであり,生産者消費者モデルは,条件変数,反発ロックでメンテナンスされる.鍵をかける代価はやはり高いと感じて、CASと比較したことがありません.
    ステータスマシンとコールバック関数の問題についてはmuduoは処理できません(少なくとも処理しにくいと思います).改善案はTaskの関数を変えて、中にパラメータを入れて、例えば状態、コールバック関数、パラメータなど、これでずっとよくなります.
    //  Task 
    typedef std::function Task;
    
    //  
    typedef std::function Task;
    

    タイマ


    set+タイムラインで実現したのは、うーん、タイムラインがもっと適切だと感じました.
    2つのset、timers、activeTimersをメンテナンスし、1つは通常の状況で、各種のタスクを保存し、もう1つはcancelタスクの時にタスクが正しくcancelされることを保証します.
    getExpiredでは期限切れのタスクをtimesから削除するので、実行が完了したらrepeatタスクがあれば追加します.では、実行するときにcancelコマンドを呼び出すと、timesの中でこのタスクを見つけることはできません.このときactiveTimersは役に立ちます.今activeTimersの中で探しています.見つけたら、cancelingTimersに参加します.見つからないのは存在しないタスクをキャンセルすることです.気にしないでください.タスクを実行してresetを望むと、タスクがcancelingTimers内にある場合はresetはアップしません.

    同時接続の制限


    このmuduoは空きファイル記述子で完成した.
    具体的には、1つのファイル記述子で空きファイルを指し、接続がいっぱいになったら、このファイル記述子でこの新しい接続を迎え、closeが落ちて空きファイルを指し、このように往復します.これによりbusy loopは発生せず、clientもサーバが忙しいことを知っています.
    改めて見るとやはりポーズが上がります.