C++ マルチプロセス マスターワーカー作業メカニズムの比較的完全な実装、およびエッジとクラウド間の共同作業の実現

I. 概要

倉庫の場所: https://gitee.com/liudegui/cpp_master_worker.git
Python を使用してマスター エンドを作成する場合は、私の別の記事を参照してください: cpp によって記述された tcp サーバー、cpp および Python 言語で tcp クライアントを提供するバージョン C++ の部分は、boost.asio ネットワーク ライブラリに基づいています。

名前 説明
マスタープロセス (master_app) ワーカー プロセスのデーモン プロセスである監視および管理エンジンは、ワーカー プロセス ポリシーの配信を提供し、ワーカー プロセスのデータとレポートを収集します。
ワーカー プロセス (worker_app) ストリームのデコード、分析、推論プロセス
動画オーバーレイ サービスの追跡 (draw-track-server) 動画に軌跡を描くサービス「openresty」をベースに
  • プロジェクトの特別な要件により、マルチプロセスのマスターワーカー作業メカニズムを設計する必要があります。

  • マスター プロセス: ワーカー プロセスのデーモン プロセスであり、エンジンの監視と管理、ワーカー プロセス ポリシーの配信の提供、ワーカー プロセス データの収集とレポートを行います。ネットワーク通信モジュール、プロセス管理モジュール、ハートビート検出モジュール、データカプセル化およびカプセル化解除モジュールが含まれています。

  • waker プロセス: ビデオ データのデコードと推論をそれぞれ担当する 2 つの作業スレッドが含まれています。処理された結果は、カスタム シリアル化によって文字ストリームにカプセル化され、マスター プロセスに送信されます。推論スレッドについては、公式の opencv に基づいています。顔認識の変更は、主にこのフレームワークの機能を説明するためのものです。

  • トラック ビデオ オーバーレイ サービス (draw-track-server): このソリューションは組み込みデバイスで使用されるため、組み込みデバイスに関連する後処理操作が多すぎると、組み込みデバイスのリソースが多く占有されます。したがって、後処理ビジネスの一部を処理のために x86 サーバーに配置することを検討してください。これにより、トラジェクトリ オーバーレイ サービスが存在します。

  • 将来的に複数の組み込み機器が並行して動作することを考慮して、ネットワーク通信には zmq が使用されます。単一のマシンでは zmq の ipc モードを使用し、複数のマシンが並行して動作する場合は zmq の tcp モードを使用します。

  • マスター プロセス、ワーカー プロセス、トラジェクトリ オーバーレイ サービスの間のデータ転送では、カスタム シリアライゼーション モジュールを使用します

  • ウェアハウス コードの master_app、worker_app、および draw-track-server はすべて個別にテストできます。詳細については、ウェアハウス コードの mock で始まるテスト コードを参照してください。

2. マスター プロセスとワーカー プロセス間の管理と相互作用

プロジェクトの実際のニーズに応じて、分析エンジンはマスター ワーカー メカニズムを使用し、1 つのマスター プロセスが複数のワーカー プロセスを管理します。

1. マスターがワーカー プロセスを管理する

ここに画像の説明を挿入

上記のように

  • マスター プロセスは、ワーカー プロセスの開始と停止を担当します。
  • マスター プロセスからワーカー プロセスに渡されるパラメーターには、一意のシリアル番号 (0 ~ 99) しかありません。

2. マスター ハートビートがワーカー プロセスを検出する

ここに画像の説明を挿入

上記のように:

  • マスター プロセスとワーカー プロセスは、共有メモリに基づいてハートビートを実行します。
  • マスター プロセスは、さまざまなワーカー プロセス ID に従って共有メモリを作成します。
  • ワーカー プロセスは、共有メモリ内のスカラーを定期的にインクリメントします。
  • マスター プロセスは、共有メモリ スカラーが増加しているかどうかを定期的にチェックします。3 回連続してチェックしても増加がなければ、元のワーカー プロセスは強制終了され、新しいプロセスが作成されます。

3. マスター プロセスとワーカー プロセス間の情報のやり取り

ここに画像の説明を挿入

上記のように:

  • マスター プロセスとワーカー プロセスは、サブスクリプション パブリッシング モデルを使用した zmq 通信に基づいており、各チャネル (ipc) は一方向に通信します。
  • マスター プロセスは server.ipc をバインドし、すべてのワーカー プロセスの ipc にサブスクライブします。
  • ワーカー プロセスはマスター プロセス ipc にサブスクライブし、それ自体の ID に従ってメッセージをフィルター処理します。同時に、マスター プロセスがサブスクライブするように {id}.ipc をバインドします。

また、マスタープロセスとワーカープロセス間の情報のシリアライズは、構造体をjson文字列にシリアライズしたり、memcpy構造体を文字列ストリームにシリアライズしたりせず、C++14のindex_sequenceを使用します。詳細については、「serialize」を参照してください。 .hpp" .

4. 検出と報告のプロセス

ここに画像の説明を挿入

上記のように:

  • マスター プロセスはカメラ情報をそれぞれ異なるワーカー プロセスに送信し、ワーカー プロセスはメッセージを受信した後、
    • 1) カメラ情報を分析してストリーム情報を取得します。
    • 2) デコードと推論のスレッドを開始し、ストリームのデコードと推論のフェッチを開始します。
  • ワーカー プロセスは継続的に検出を行い、イベントが検出されると、イベント トラックとビデオをマスターに送信します。マスター プロセスは単純にそれを処理した後、イベントとトラックをトラック オーバーレイ サービスに送信します。
  • オーバーレイ サーバーがビデオとトラックを受信した後、
    • 1) 描画モジュールを呼び出し、ビデオと軌跡を重ね合わせ、新しいビデオを生成します。
    • 2) スーパーインポーズされたビデオと関連情報を他の http サーバーに送信します。

5. マスター プロセスがワーカー プロセス フローを開始する

1. プログラム cfg 構成ファイルを読み取り、ワーカー プロセス名、開始するワーカー プロセスの数、共有メモリのタイミング チェックを開始するかどうか、およびその他の構成を取得します。

2. 構成情報に従ってワーカー プロセスを開始し、マスター プロセスとワーカー プロセスは合意に従って wawrid (ID00、ID01 など) と通信します。

3. 共有メモリのタイミング チェックが有効な場合、事前に共有メモリが作成され、フラグ ビットがワーカー プロセスによって定期的に更新されているかどうかを確認するタイマーが作成されます。回、プロセスが強制終了され、新しいプロセスが作成されます。

4. マスタープロセスはカメラ情報ファイルを読み取り、読み取った情報の順に構造体をワーカープロセスに送信し、カメラ情報の数とワーカーの数が一致しない場合は、2 つの最小量を送信します。

3. プログラム構成

1. master_app プロセス

プログラム構造

ここに画像の説明を挿入

マスターモジュール間の関係

ここに画像の説明を挿入

補足事項

  • ini と json の両方の構成ファイルは、boost.property_tree を使用して読み込まれます。詳細については、appconfig_readerand json_message_processor(フィールドが空であると判断されました);を確認してください。

  • プロセス管理は boost.process カプセル化に基づいており、クロスプラットフォームに対応できない一部の部分はマクロ処理されます。

  • http_upload は boost.asio パッケージに基づいており、通常の http ポストと multipart/form-data ポストをサポートし、複数のファイルと文字列を同時にアップロードできます。

  • ハートビート チェックは、boost.interprocess の共有メモリ カプセル化に基づいており、ワーカーとペアにする必要があり、構成ファイルで無効にすることができます。

  • zmq の受け入れ (recv) は完全にブロックされており、このために別のスレッドが作成されます; libzmq ライブラリを参照しながら、zmq.hpp パッケージも参照します。詳細については、関連するヘッダー ファイルを参照してください;

  • messagehandler と他のモジュールを疎結合するには、"message bus" 関連付けを使用します。詳しくは、messagebus.hppboost::any; を使用する必要があります。

  • マスター プロセスとワーカー プロセスは最終的にフォルダーにデプロイされるため、すべてのモジュールは静的な .a ライブラリにコンパイルされ、.so コンポーネントが混乱するのを防ぎます。

  • loghelper はウェアハウスの別のログ ライブラリであり、boost.log ワッパーです; コンソール、ファイル、および syslog に出力でき、C++ "<<" および C タイプの "printf" をサポートします. 詳細については、を参照してください倉庫コード。

2. worker_app プロセス

プログラム構造

ここに画像の説明を挿入

ワーカー プロセス モジュールの関係

ここに画像の説明を挿入

補足事項

(内容の一部は原盤と重複しています)

  • decode_video: ffmpeg を使用し、CPU デコード、amd64 プラットフォームでの cuda デコード、NX プラットフォームでの Nvmpi デコードをサポートします。

  • zmq の受け入れ (recv) は完全にブロックされており、このために別のスレッドが作成されます; libzmq ライブラリを参照しながら、zmq.hpp パッケージも参照します。詳細については、関連するヘッダー ファイルを参照してください;

  • message_handler と他のモジュールを疎結合するには、「メッセージ バス」関連付けを使用します。詳しくは、messagebus.hppboost::any; を使用する必要があります。

  • マスター プロセスとワーカー プロセスは最終的にフォルダーにデプロイされるため、すべてのモジュールは静的な .a ライブラリにコンパイルされ、.so コンポーネントが混乱するのを防ぎます。

  • デコード スレッドと推論スレッドの間にメッセージ キュー キャッシュを追加し、オープン ソースを使用しますconcurrentqueue。このコンポーネントは内部的にスレッド同期をサポートします。

  • ワーカー プロセスは個別にデバッグでき、コンパイル中にマクロを追加できますWORKER_DEBUG

  • loghelper はウェアハウスの別のログ ライブラリであり、boost.log ワッパーです; コンソール、ファイル、および syslog に出力でき、C++ "<<" および C タイプの "printf" をサポートします. 詳細については、を参照してください倉庫コード。

4. 軌跡動画オーバーレイサーバー

1. プログラム構成

ここに画像の説明を挿入

上記のように:

1. video_bbox_drawer: C++ で記述されたトラックおよびビデオ オーバーレイ モジュールで、標準の C インターフェイス関数を提供します。

2. draw-track-server: openresty フレームワークに基づいて記述された http トラック オーバーレイ サービスの場合、lua 言語を使用してビジネスを記述し、video_bbox_drawer の c インターフェイスを呼び出します。

3. http_test_client: http_upload を使用してテスト トラックとビデオを送信するための http クライアント プログラムは、engine-master と同じである必要があります。

2.ワークフロー

1. nginx は http メッセージを受信し、処理のために do_upload.lua に転送します。

2. do_upload.lua は、メッセージをトラック テキストとビデオ ファイルに解析します。

3. libvideo_bbox_drawer.so をロードし、c インターフェイス関数を呼び出し、トラックとビデオ ファイルをスーパーインポーズします。

5. 主要構造の設計

  • レポート検出トラック: この構造はワーカーとトラック オーバーレイ サービスによって参照され、2 つが一貫している必要があります。
struct Rect_t
{
    uint32_t x   = 0;       //
    uint32_t y   = 0;       //
    uint32_t w   = 0;       // 宽
    uint32_t h   = 0;       // 高
};

struct Track_t
{
    uint32_t f   = 0;       // 帧序号
    Rect_t  rect;           //
};

// 上报轨迹信息
struct TrajectoryInfo_t
{
    std::string             video_name;
    uint32_t                video_width;
    uint32_t                video_height;
    uint32_t                video_framerate;
    std::vector<Track_t>    tracks;
};
  • ZMQ メッセージ通信構造: 以下は、マスター プロセスとワーカー プロセス間の相互作用に使用される構造であり、2 つのプロセスは一貫している必要があります。
// 摄像机下发信息
struct CameraInfo_t
{
    char name[64]               = {0};     // 摄像机名称
    char main_stream[128]       = {0};     // 主流rtsp url
    char alg_param_file[128]    = {0};     // 算法库配置文件
    char camera_id[64]          = {0};     // id
    uint32_t main_pixel_w         = 0;     // width
    uint32_t main_pixel_h         = 0;     // hight
    uint32_t main_frame_rate      = 0;     // 帧率
};

// 需要上传给httpserver
struct VideoAndTracks_t
{
    std::string tracksStr;                  // 轨迹(未base64)
    std::string videoName;                  // 视频文件名
    std::string videoData;                  // 视频文件内容
};

6. ソフトウェア開発は

C++ 部分: C++11、libboost1.66+、libzmq、libffmpeg4.2+、libopencv4.4+

openresty: システムはデフォルトでインストール可能

** cpp_master_worker ** サードパーティ ライブラリのアドレスに依存

  • loghelper : これは、私が使用してきた boost.log ベースのログ ライブラリです。
  • concurrentqueue : C++11 用の高速なマルチプロデューサー、マルチコンシューマーのロックフリー同時キュー
  • libzmq : C++ の ZeroMQ コア エンジン、ZMTP/3.1 を実装cppzmq : libzmq のヘッダーのみの C++ バインディング

これらは、CSDN にアップロードされた 3 つのオープン ソース プロジェクト コードであり、https://download.csdn.net/download/stallion5632/86247799 からパッケージ化およびダウンロードできます。

おすすめ

転載: blog.csdn.net/stallion5632/article/details/125946689