私は自分の仕事に多くの設計要件があるスレッドプールの設計を考え出そうとしています。これは、ソフトウェアを動作させるための実際の問題であり、難しい作業です。私は実用的な実装を持っていますが、これをSOに投げて、人々がどのような興味深いアイデアを思い付くことができるかを見て、私の実装と比較して、それがどのように積み重なるかを確認したいと思います。私はできる限り要件に具体的にしようとしました。
スレッドプールは一連のタスクを実行する必要があります。タスクは、短時間実行(<1秒)または長時間実行(数時間または数日)にすることができます。各タスクには関連する優先度があります(1=非常に低いから5=非常に高い)。タスクは他のタスクの実行中にいつでも到着する可能性があるため、タスクが到着すると、スレッドプールはこれらを取得し、スレッドが使用可能になったときにスケジュールする必要があります。
タスクの優先度は、タスクの長さに完全に依存しません。実際、タスクを実行するだけで、タスクの実行にかかる時間を知ることは不可能です。
一部のタスクはCPUバウンドですが、一部はIOバウンドです。特定のタスクが何であるかを事前に知ることは不可能です(ただし、タスクの実行中に検出できる可能性があると思います)。
スレッドプールの主な目標は、スループットを最大化することです。スレッドプールは、コンピューターのリソースを効果的に使用する必要があります。理想的には、CPUにバインドされたタスクの場合、アクティブなスレッドの数はCPUの数と等しくなります。IOバウンドタスクの場合、ブロッキングがスループットに過度に影響しないように、CPUよりも多くのスレッドを割り当てる必要があります。ロックの使用を最小限に抑え、スレッドセーフ/高速コンテナを使用することが重要です。
一般に、CPU優先度の高いタスクを実行する必要があります(参照:SetThreadPriority)。優先度の低いタスクは、優先度の高いタスクの実行を「ブロック」してはなりません。したがって、優先度の低いタスクがすべて実行されているときに優先度の高いタスクが実行されると、優先度の高いタスクが実行されます。
タスクには、「最大実行タスク」パラメーターが関連付けられています。各タイプのタスクは、一度に最大でこの数のタスクの同時インスタンスのみを実行できます。たとえば、キューに次のタスクがあるとします。
- A-1000インスタンス-低優先度-最大タスク1
- B-1000インスタンス-低優先度-最大タスク1
- C-1000インスタンス-低優先度-最大タスク1
動作する実装は、(最大で)1 A、1 B、および1Cしか同時に実行できませんでした。
Windows XP、Server 2003、Vista、およびServer 2008(最新のサービスパック)で実行する必要があります。
参考までに、次のインターフェイスを使用する場合があります。
namespace ThreadPool
{
class Task
{
public:
Task();
void run();
};
class ThreadPool
{
public:
ThreadPool();
~ThreadPool();
void run(Task *inst);
void stop();
};
}