2
  class Process
{
    static void Main(string[] args)
    {
        int threads = 0;
        int processes = 0;
        Console.WriteLine("Total number of processes:");
        processes = Convert.ToInt32(Console.ReadLine());
        Console.WriteLine("Enter number of parallel threads:");
        threads = Convert.ToInt32(Console.ReadLine());

        ManualResetEvent[] events = new ManualResetEvent[threads];

        int k = 0, innercount = 0;           
        //----running in bunches
        do
        {
            for (int l = 0; l < threads; l++)
            {
                if (k < threads)
                {
                    events[l] = new ManualResetEvent(false);
                    Runner r = new Runner(events[l], innercount);
                    new Thread(new ThreadStart(r.Run)).Start();
                    Console.WriteLine("running start...{0}", innercount);
                    k++;
                    innercount++;
                }
            }
            WaitHandle.WaitAny(events);
            k--;
            Console.WriteLine("Decrement counter...{0}", k);
        }
        while (innercount < processes);

        WaitHandle.WaitAll(events);

        Console.WriteLine("All finished!");

        Console.ReadLine();

    }
}
 class Runner
{
    static readonly object rngLock = new object();
    static Random rng = new Random();

    ManualResetEvent ev;
    int id;

    internal Runner(ManualResetEvent ev, int id)
    {
        this.ev = ev;
        this.id = id;
    }

    internal void Run()
    {

            int sleepTime;
            lock (rngLock)
            {
                sleepTime = rng.Next(2000);
            }
            Thread.Sleep(sleepTime);
            Console.WriteLine("Thread Runner {0}",
                               id);
            if (ev.Set())
            {
                Console.WriteLine("release thread...{0}", id);
            }
    }
}

複数のスレッドを実行する必要があります.1つのスレッドが終了したら、別のスレッドを開始します.問題は、すべてのプロセスを同時に開始することです.(この条件はうまく機能していないようです WaitHandle.WaitAny(events);)

1: 20 個のスレッドが実行されている場合、20 番目のスレッドから 1 つのスレッドが解放されると、21 番目のスレッドが開始されます。

2: スレッドプールを使用せずに、EventWaitHandler を使用して実行できます。

4

2 に答える 2

1

PLinqと. _WithDegreeOfParallelism

WithDegreeOfParallelism同時に実行するスレッドの数を制限します。

次の例は、Plinq を使用して多数のワーカーを実行し、制限付きの並列処理で各ワーカーに異なるオブジェクトを渡す方法を示しています。

一連のオブジェクトから開始し、それらの各オブジェクトをワーカー メソッドに渡したいと想定しています。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace Demo
{
    class DataForWorker
    {
        public int ID;
        public string Value;
    };

    class Program
    {
        Random rng = new Random();
        int numberOfThreadsRunning;

        void Run()
        {
            int maxThreads = 8;

            IEnumerable<DataForWorker> dataForWorkers = getDataForWorkers();

            dataForWorkers
                .AsParallel()
                .WithDegreeOfParallelism(maxThreads)
                .ForAll(worker);
        }

        IEnumerable<DataForWorker> getDataForWorkers()
        {
            // Just return some dummy data.

            int numberOfDataItems = 30;

            return Enumerable.Range(1, numberOfDataItems).Select
            (
                n => new DataForWorker
                {
                    ID = n,
                    Value = n.ToString()
                }
            );
        }

        void worker(DataForWorker data)
        {
            int n = Interlocked.Increment(ref numberOfThreadsRunning);
            Console.WriteLine("Thread " + data.ID + " is starting. #threads now = " + n);
            Thread.Sleep(rng.Next(1000, 2000));
            Console.WriteLine("Thread " + data.ID + " is stopping.");
            Interlocked.Decrement(ref numberOfThreadsRunning);
        }

        static void Main()
        {
            new Program().Run();
        }
    }
}
于 2013-05-31T08:04:22.473 に答える
1

セマフォを使用して、スレッドの解放を制御してみてください。そこの例を見てください。しかし、なぜThreadPoolこれを達成するために使用できないのだろうか?

セマフォのカウントは、スレッドがセマフォに入るたびに減少し、スレッドがセマフォを解放すると増加します。カウントがゼロの場合、後続の要求は、他のスレッドがセマフォを解放するまでブロックされます。すべてのスレッドがセマフォを解放すると、カウントはセマフォの作成時に指定された最大値になります。

このように、スレッドがセマフォのスロットを解放すると、別のスレッドがそのスロットを占有して実行できます。

于 2013-05-31T07:45:27.150 に答える