@Roddy - あなたが指し示しているリンクをすでに読みました。どちらも、Paul Tyma のプレゼンテーション「何千ものスレッドとブロッキング I/O - Java サーバーの古い書き方が再び新しくなりました」から参照されています。
ただし、Paul のプレゼンテーションから必ずしも飛び出しているとは限らないことのいくつかは、起動時に -Xss:48k を JVM に指定したことと、JVM の NIO 実装が有効であるためには効率的であると想定していることです。比較。
Indy は、同様に縮小され、厳密に制約されたスタック サイズを指定していません。Indy コードベースには、BeginThread (Delphi RTL スレッド作成ルーチン。このような状況で使用する必要があります) または CreateThread (生の WinAPI 呼び出し) への呼び出しはありません。
デフォルトのスタック サイズは PE に格納され、Delphi コンパイラの場合、デフォルトで 1MB の予約済みアドレス空間に設定されます(スペースは、OS によってページごとに 4K チャンクでコミットされます。実際、コンパイラは、次の場合にページにアクセスするコードを生成する必要があります。拡張機能はページ フォールトによって制御されますが、スタック内の最下位 (ガード) ページに対してのみ制御されるため、関数には 4K を超えるローカルが存在します)。つまり、最大 2,000 の同時スレッドが接続を処理した後、アドレス空間が不足することになります。
現在、{$M minStackSize [,maxStackSize]} ディレクティブを使用して PE のデフォルトのスタック サイズを変更できますが、これはメイン スレッドを含むすべてのスレッドに影響します。48K または (同様の) スペースは多くないため、あまり再帰を行わないでください。
さて、特に Windows の非同期 I/O の非パフォーマンスについて Paul が正しいかどうかは、100% 確信が持てません。確実にするには、測定する必要があります。ただし、私が知っていることは、スレッド化されたプログラミングが非同期イベントベースのプログラミングよりも簡単であるという議論は、誤った二分法を提示していることです。
非同期コードはイベント ベースである必要はありません。.NET の場合のように、継続ベースにすることができます。また、継続としてクロージャーを指定すると、状態が無料で維持されます。さらに、線形スレッド スタイルのコードから継続渡しスタイルの非同期コードへの変換は、コンパイラによって機械的に行うことができるため (CPS 変換は機械的に行われます)、コードの明快さを犠牲にする必要もありません。