5

重複の可能性:
タスクとスレッドの違いは何ですか?

タイトル自体が重複した質問のように見えることは理解していますが、このトピックに関連する以前の投稿をすべて読みましたが、プログラムの動作はまだよくわかりません。

現在、約 1,000 の電子メール アカウントをチェックする小さなプログラムを作成しています。各スレッド/タスクの計算コストは​​高くありませんが、各スレッドの継続時間はネットワーク I/O に大きく依存しているため、間違いなくマルチスレッドまたはマルチタスクが正しいアプローチであると感じています。

そのようなシナリオでは、スレッド/タスクの数をコア数よりもはるかに多く設定することも合理的であると思います。(i5-750 の場合は 4 つ)。したがって、スレッドまたはタスクの数を 100 に設定しました。

タスクを使用して記述されたコード スニペット:

        const int taskCount = 100;
        var tasks = new Task[taskCount];
        var loopVal = (int) Math.Ceiling(1.0*EmailAddress.Count/taskCount);

        for (int i = 0; i < taskCount; i++)
        {
            var objContainer = new AutoCheck(i*loopVal, i*loopVal + loopVal);
            tasks[i] = new Task(objContainer.CheckMail);
            tasks[i].Start();
        }
        Task.WaitAll(tasks);

スレッドを使用して記述された同じコード スニペット:

        const int threadCount = 100;
        var threads = new Thread[threadCount];
        var loopVal = (int)Math.Ceiling(1.0 * EmailAddress.Count / threadCount);

        for (int i = 0; i < threadCount; i++)
        {
            var objContainer = new AutoCheck(i * loopVal, i * loopVal + loopVal);
            threads[i] = new Thread(objContainer.CheckMail);
            threads[i].Start();
        }
        foreach (Thread t in threads)
            t.Join();
        runningTime.Stop();
        Console.WriteLine(runningTime.Elapsed);

では、これら2つの本質的な違いは何ですか?

4

2 に答える 2

7

タスクは必ずしもスレッドに対応しているわけではありません。それらは、スレッド コードよりもはるかに効率的な方法で、タスク ライブラリによってスレッドプール スレッドにスケジュールされます。

スレッドの作成にはかなりのコストがかかります。タスクはキューに入れられ、スレッドが使用可能になると再利用されるため、スレッドがネットワーク IO を待機しているときに、別のタスクを実行するために実際に再利用できます。アイドル状態のスレッドは無駄なリソースです。プロセッサ コア数に対応する数のスレッドしか (同時に) 実行できないため、100 スレッドは、すべてのコアでそれぞれ少なくとも 25 回のコンテキスト スイッチを意味します。

タスクを使用している場合は、1000 個の電子メール処理タスクをすべてキューに入れ、それらをまとめてリッピングするのではなく、キューに入れます。タスク ライブラリは、それを実行するスレッド数を処理します。

于 2012-10-16T20:07:41.933 に答える
0

並べ替えの簡単な答えは、タスクはスレッドと等しくないということです。タスクはタスク スケジューラでキューに入れられ、スレッドで実行されますが、100 個のタスクをキューに入れても、100 個のスレッドが実行されるわけではありません。

通常、タスクは、有限サイズのスレッド プールのスレッドで実行されます。これらのスレッドがすべてビジー状態になると、タスクはスレッドがタスクを実行できるようになるまで待機する必要があります。また、適切なタスク スケジューラを使用して UI スレッドなどでキューに入れることもできます。この場合、UI スレッドのメッセージ ループによって同期的に実行されます (これは、UI と対話しているときに役立ちます)。

タスクの例では、開始するタスクの数を実際に制限する必要はありません。タスクは既にキューに入れられており、それらを実行できるスレッドができるまで待機する必要があるためです。スレッドを処理するのに十分な CPU/メモリがあると仮定するのではなく、システムが処理できるものに基づいてスレッドの最大数をシステムに決定させるため、これがおそらく最良のアプローチです。

スレッドを使用した例は、割り当てているスレッドの数を確実にスピンアップすることを明確に意味します。

于 2012-10-16T20:08:59.797 に答える