如何在不使用threadPool的情况下在线程束中运行进程数和使用EventWaitHandler进行处理


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

我必须运行多个线程。如果一个线程结束,那么启动另一个线程。问题是它同时启动了所有的进程。(似乎这个条件不工作好waitthandle . waitany(事件);)

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

2:不使用线程池,可以使用EventWaitHandler。

可以用PLinq和WithDegreeOfParallelism做点什么。

WithDegreeOfParallelism将限制同时运行的线程数。

下面的例子展示了如何使用Plinq以有限的并行度运行多个worker,并向每个worker传递一个不同的对象。

它假设您从一个对象序列开始,并且您希望将每个对象传递给一个工作方法:

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

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

每次线程进入时,信号量的计数递减信号量,并在线程释放该信号量时递增。当计数为零,后续请求阻塞,直到其他线程释放信号量。当所有线程都释放了信号量时,计数处于信号量失效时指定的最大值创建。

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

相关内容

  • 没有找到相关文章

最新更新