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);
            }
    }
}

我必须运行多个线程。如果一个线程完成然后启动另一个线程。问题是它同时启动了所有进程。(似乎这种情况不能正常工作 WaitHandle.WaitAny(events);)

1:如果有 20 个线程正在运行,那么当一个线程从 20s 线程释放时,将启动第 21 个线程。

2:不使用线程池可以使用EventWaitHandler来完成。

4

2 回答 2

1

尝试使用Semaphore来控制线程的释放。看看那里的例子。但我想知道为什么你不能ThreadPool用来完成这个?

每次线程进入信号量时,信号量上的计数都会减少,而当线程释放信号量时,计数会增加。当计数为零时,后续请求会阻塞,直到其他线程释放信号量。当所有线程都释放信号量时,计数为创建信号量时指定的最大值。

这样,一旦一个线程释放了信号量中的一个槽,另一个线程就可以占用该槽并运行。

于 2013-05-31T07:45:27.150 回答
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 回答