クロスプラットフォームの基礎となるライブラリ https://github.com/hujianzhe/util をダウンロードして、BootServer ディレクトリに配置します
導入:
このコードは、サービス ノードの起動ブートストラップ、タスクのスケジューリング、および基本的なモジュールの記述のみを実装しています。これには、純粋な C で実装されており、使用機能に関しては非常に制限されています。いくつかの一般的な共通プロトコル フローを実装し、C++ をサポートします。20 スタックレス コルーチンの拡張であり、C++ がフレームワーク層を汚染して動的ライブラリの生成に影響を与えるのを防ぐために、純粋な C 動的ライブラリの一部のコードから分離されています。
util のコードはクロスプラットフォームに対応しますが、サードパーティ ライブラリのインストールは必要ありません。
操作プロセスの紹介:
ビジネス プロセスは、コードによってコンパイルされた動的ライブラリを呼び出し、使用する対応するインターフェイスを呼び出します。呼び出しプロセスの詳細については、テスト ノードの例を参照してください (BootServer ディレクトリ内の main_template は、プロセスベースの起動コード テンプレートのセットです)。
複数のスレッドがモジュール内のネットワーク IO の読み取りと書き込みを処理します。最初に別のアクセス許可スレッドがワーカー スレッドを開き、内部メッセージと受信したネットワーク メッセージを処理し、それらをビジネス コード ロジックにディスパッチします。ワーカー スレッドは、処理のスケジュール設定にスタック コルーチンを使用します (スタックレス コルーチンが使用されない理由については、以下を参照してください)。
ワーカー スレッドは、最高の互換性を維持するためにデフォルトでスタック コルーチンを使用します。また、スタック コルーチンとスタックレス コルーチンが共存できます。
モジュールの紹介とサンプルコード:
1. BootServer: メインコード部分、サービスノードの必要な初期化と操作
2. ServiceTemplate: ビジネス ロジックの作成に使用されるサービス ノード コード テンプレート
3. SoTestClient、SoTestServer: ノードをテストし、いくつかのサンプル コードを作成しました
4. Cpp20-SoTestServer: テスト ノード、サンプル コードを作成し、main.cpp で C++20 スタックレス コルーチンを有効にしました (util ライブラリの C++20 スタックレス コルーチン スケジューラを使用)
コンパイル:
Windows の直接 VS コンパイル
Linux/Mac OS X で make debug / make release / make asan を使用する
起動する:
サービス ノードの起動に必要な構成ファイルを編集し (特定の形式については、添付の構成ファイル テンプレートを参照)、各ノードに構成ファイル、一意の ID、ログ識別名、IP、およびポート番号を指定します。
Windows は VS で直接開き、プロジェクトは起動パラメータ <構成ファイル> で構成されます。
Linux/Mac がコンパイルされた後、sh run.sh <サービス プロセス> <構成ファイル>
設計上の理由と洞察: Q: スタックレス コルーチンを使用せず、スタック コルーチンを使用するのはなぜですか? A: 純粋な C でスタックレス コルーチンを実装するのは簡単です (コードの詳細については、util ライブラリで純粋な C で実装されたスタックレス コルーチン スケジューラを参照してください) が、リソースのリサイクルと永続性 (特にスタック上の変数はコルーチンの再定義の影響を受けます) -entry) (後者の状況) は非常に困難です。スタックレス コルーチンをスムーズに使用したい場合は、やはりコンパイラ サポートに依存する必要があります。これは C++20 で実現されており、util ライブラリには完全な C++20 スタックレス コルーチン スケジューラの実装もあります。
Q: スタックレス コルーチンがこの拡張機能をヘッダー ファイルの形式で提供するのはなぜですか?
A: 1. スタックレス コルーチンはコードに侵入的であり、多数の関数署名形式を変更するためです。
2. C で認識されない C++ オブジェクトが含まれているため、ダイナミック ライブラリを正常にエクスポートできません。
3. ヘッダー ファイルの形式で与えられ、スタックレス コルーチンのアクティブ化許可をアプリケーション層に渡すことが、純粋な C ダイナミック ライブラリ部分を汚染することなく処理するために現在私が考えている方法です。
Q: 他のスケジューラーと置き換えることはできますか?
A: ワーカー スレッドのスケジューラは置き換えることができます。ワーカー スレッドは、スケジューラの実行キャリアとして設計されており、フレームワーク内のネットワーク スレッドとワーカー スレッド間の対話は、インターフェイス フックを介したスケジューリング動作に対応できます。
Q: 他のネットワーク ライブラリと置き換えることはできますか?
A: 1. 現時点では他のネットワーク ライブラリで置き換えることはできませんが、この問題は設計の開始時に考慮されており、将来的には、ワーカー スレッドと同様に対応する動作がネットワーク部分とタスク スケジューリング部分で完全に分離されます。フックは交換用に提供されます。
2. サードパーティのネットワーク ライブラリは多数ありますが、焦点は異なります。アプリケーション開発に使用される TCP および UDP ライブラリがあり、ユニバース全体を含めたいライブラリもあり、アプリケーション層でネットワーク プロトコル スタック全体を実装するライブラリもあり、実際にはこの領域は統一されていません。
3. 将来、ネットワーク ライブラリのセットが標準に組み込まれる場合は、それを置き換えます。
Q: フレームワークとして C++ を使用しないのはなぜですか?
A: 1. このコード セットが作成された時点では、C++20 はまだ登場していませんでした。これは、対応するプラットフォーム システム API を呼び出すことで C を使用して実行できました。
2. この種のフレームワークは実装する機能が固まっており、リソースのライフサイクルもプロセスごとに固まっているので、純粋なCで実装すれば十分です(以前はC++で実装したバージョンもありましたが、コードはもっと複雑でした)
3. ダイナミック ライブラリが他のモジュールによって呼び出される場合でも、C でインターフェイスをシールする必要があります。
4.C++ でエクスポートされたクラスは伝染性があり、ABI は統一されていません
Q: ビジネス層は純粋な C を使用して開発し続けることができますか?
A: 高級言語で書かれたモジュールで非同期処理や例外をスローする記述は、リソース破棄のタイミングが不確実になるため、現時点では純粋な C を使用してリソースを手動で制御することは非常に困難であるため、あまりお勧めできません。たとえば、C++ を使用して上位レベルのビジネス コードを開発すると、その RAII メカニズムによって対応するリソースが確実にリリースされます。
Q: 古いプロジェクトの「コールバック」を「コルーチン」に変換したい場合、スケジューラ部分をビジネス コード内の対応するコール ポイントに置き換えるだけでよいですか?
A: それはそれほど単純ではありません。また、コールバック形式であっても、コルーチン形式であっても、本質的には、この期間中にリクエストを発行して結果を待つことです。解決しなければならない問題であり、慎重に検討する必要があります。Raw ポインタの場合、プロジェクトで使用されている場合はほとんど変換できないと言えます。 std::shared_ptr などの手段は変数のライフサイクルを長くするため、「スタック コルーチン」バージョンへの変換は難しくなりません。C++20 スタックレス コルーチンに変換したい場合、作業負荷は膨大になります。これはプロジェクトを書き換えることに等しいため (スタックレス コルーチンには強力なコード侵入があるため)、古いプロジェクトを変換しないことをお勧めします。
Q: 現在、コルーチンを別のスレッドに移行して実行することが許可されていないのはなぜですか?
A: コルーチンの移行は簡単に行うことができますが、提供されていない理由は次のとおりです。
1. コルーチン間で実行されるタスクは不確実であるため、同じスケジューリング スレッド内で IO と計算が混在する可能性があります。
2. 移行後、同じコルーチン プロセスが異なるスレッドで実行される可能性があります。この場合、コードがスレッド ローカル変数に依存していないことを確認する必要がありますが、サードパーティ ライブラリがスレッド ローカル変数を使用しないことを保証することはできません。 。
Q: コンパイルおよび実行時に asan はクラッシュしますか?
A: 1. フレームワークのデフォルトのスタック型コルーチンを使用している場合、これはコードの問題ではありません。ノード構成ファイルでスタック型コルーチンのスタック サイズを調整できます (ASAN が有効な場合、比較的大きなスタック スペースが消費されます)。スタック爆発の可能性あり)
2. ASAN は Unix 環境のスタック コルーチン API (ucontext) を完全にはサポートしていません。ucontext コルーチン API は util コードで ASAN に適応されていますが、ASAN での実行に問題がないことを 100% 保証することはできません。 (今のところとても良い環境です)
3. 一部の新しい Linux ディストリビューションでは、ASAN が AddressSanitizer: DEADLYSIGNAL を無限に出力する場合、sudo sysctl vm.mmap_rnd_bits=28 を調整して問題を解決します。
TODO:
1. 詳細なドキュメントを書く時間が本当にありません。
2. スクリプト言語でビジネス ロジックを作成するためのサポートを提供する