79

バックグラウンド:

私は現在、多くの (数百から数千の) スレッドを持つアプリケーションを持っているため、これを求めています。これらのスレッドのほとんどは、作業項目がキューに入れられるのを待って、ほとんどの時間アイドル状態です。作業項目が利用可能になると、任意の複雑な既存のコードを呼び出して処理されます。オペレーティング システムの構成によっては、ユーザー プロセスの最大数を制御するカーネル パラメーターにアプリケーションがぶつかる可能性があるため、ワーカー スレッドの数を減らす方法を試してみたいと思います。

私の提案した解決策:

各ワーカースレッドをコルーチンに置き換えるコルーチンベースのアプローチがこれを達成するのに役立つようです。次に、実際の (カーネル) ワーカー スレッドのプールによってバックアップされるワーク キューを作成できます。アイテムが処理のために特定のコルーチンのキューに配置されると、エントリがスレッド プールのキューに配置されます。次に、対応するコルーチンを再開し、キューに入れられたデータを処理してから、再び一時停止し、ワーカー スレッドを解放して他の作業を実行します。

実装の詳細:

これをどのように行うかを考えていると、スタックレス コルーチンとスタックフル コルーチンの機能の違いを理解するのに苦労しています。Boost.Coroutineライブラリを使用してスタックフル コルーチンを使用した経験があります。概念レベルから理解するのは比較的簡単です。コルーチンごとに、CPU コンテキストとスタックのコピーを維持し、コルーチンに切り替えると、その保存されたコンテキストに切り替えます (カーネルモード スケジューラが行うように)。 )。

あまり明確でないのは、スタックレス コルーチンがこれとどのように異なるかです。私のアプリケーションでは、上記の作業項目のキューイングに関連するオーバーヘッドの量が非常に重要です。新しい CO2 ライブラリなど、私が見たほとんどの実装は、スタックレス コルーチンがオーバーヘッドの少ないコンテキスト スイッチを提供することを示唆しています。

したがって、スタックレス コルーチンとスタックフル コルーチンの機能の違いをより明確に理解したいと思います。具体的には、次の質問について考えます。

  • このような参考文献は、スタックフル コルーチンとスタックレス コルーチンのどこで譲歩/再開できるかに違いがあることを示唆しています。これは事実ですか?スタックフル コルーチンでは実行できるが、スタックレス コルーチンでは実行できない簡単な例はありますか?

  • 自動ストレージ変数 (つまり、「スタック上の」変数) の使用に制限はありますか?

  • スタックレス コルーチンから呼び出すことができる関数に制限はありますか?

  • スタックレス コルーチンのスタック コンテキストの保存がない場合、コルーチンの実行時に自動ストレージ変数はどこに移動しますか?

4

2 に答える 2

4

必要なのはユーザーランドのスレッド/ファイバーです-通常、深くネストされたコールスタックでコード (ファイバーで実行) を一時停止します (たとえば、TCP 接続からのメッセージの解析)。この場合、スタックレス コンテキスト スイッチングを使用できません (アプリケーション スタックはスタックレス コルーチン間で共有されます -> 呼び出されたサブルーチンのスタック フレームは上書きされます)。

boost.context に基づいてユーザーランドのスレッド/ファイバーを実装する boost.fiber のようなものを使用できます。

于 2015-03-12T10:25:37.020 に答える