zoukankan      html  css  js  c++  java
  • ThreadPool线程池

    1.GetMaxThreads,GetMinThreads

        class Program
        {
            static void Main(string[] args)
            {
                int workerThreads;
                int completePortsThreads;
                ThreadPool.GetMaxThreads(out workerThreads, out completePortsThreads);
                Console.WriteLine("线程池中最大的线程数{0},线程池中异步IO线程的最大数目{1}", workerThreads, completePortsThreads);
                ThreadPool.GetMinThreads(out workerThreads, out completePortsThreads);
                Console.WriteLine("线程池中最小的线程数{0},线程池中异步IO线程的最小数目{1}", workerThreads, completePortsThreads);
                Console.Read();
            }
        }

    线程不是越多越好
    ①:线程很多的话,线程调度就越频繁,可能就会出现某个任务执行的时间比线程调度花费的时间短很多的尴尬局面。
    ②:我们要知道一个线程默认占用1M的堆栈空间,如果10230个线程将会占用差不多10G的内存空间,我想普通的电脑立马罢工。

    2.SetMaxTheads,SetMinThreads

        class Program
        {
            static void Main(string[] args)
            {
                int workerThreads;
                int completePortsThreads;
                ThreadPool.SetMaxThreads(100, 50);
                ThreadPool.SetMinThreads(20, 10);
                ThreadPool.GetMaxThreads(out workerThreads, out completePortsThreads);
                Console.WriteLine("线程池中最大的线程数{0},线程池中异步IO线程的最大数目{1}
    ", workerThreads, completePortsThreads);
                ThreadPool.GetMinThreads(out workerThreads, out completePortsThreads);
                Console.WriteLine("线程池中最小的线程数{0},线程池中异步IO线程的最小数目{1}
    ", workerThreads, completePortsThreads);
                Console.Read();
            }
        }

    3.QueueUserWorkItem

    需要容纳任务并执行的方法来了,该方法有一个WaitCallBack的委托,我们只需要把将要执行的任务丢给委托,CLR将会在线程池中调派空闲的线程执行。

        class Program
        {
            static void Main(string[] args)
            {
                ThreadPool.QueueUserWorkItem(Run1);
                Console.Read();
            }
    
            static void Run1(object obj)
            {
                Console.WriteLine("我是线程{0},我是线程池中的线程吗? 
    回答:{1}", Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
            }
        }

    可能我们也需要像普通的Thread一样带一些参数到工作线程中,QueueUserWorkItem的第二个重载版本解决了我们的问题。

        class Program
        {
            static void Main(string[] args)
            {
                ThreadPool.QueueUserWorkItem(Run1, "我是主线程");
                Console.Read();
            }
    
            static void Run1(object obj)
            {
                Console.WriteLine(obj);
            }
        }

    4.RegisterWaitForSingleObject

    我们知道,如果我们把要执行的任务丢给线程池后,相当于把自己的命运寄托在别人的手上。
    ①:我们再也不能控制线程的优先级了。
    ②:丢给线程池后,我们再也不能将要执行的任务取消了。

    是的,给别人就要遵守别人的游戏规则,不过RegisterWaitForSingleObject提供了一些简单的线程间交互,因为该方法的第一个参数是
    WaitHandle,在VS对象浏览器中,我们发现EventWaitHandle继承了WaitHandle,而ManualResetEvent和AutoResetEvent都继承于
    EventWaitHandle,也就是说我们可以在RegisterWaitForSingleObject溶于信号量的概念。

        class Program
        {
            static void Main(string[] args)
            {
                AutoResetEvent ar = new AutoResetEvent(false);
                ThreadPool.RegisterWaitForSingleObject(ar, Run1, null, Timeout.Infinite, false);
                Console.WriteLine("时间:{0} 工作线程请注意,您需要等待5s才能执行。
    ", DateTime.Now);
                //5s
                Thread.Sleep(5000);
                ar.Set();
                Console.WriteLine("时间:{0} 工作线程已执行。
    ", DateTime.Now);
                Console.Read();
            }
    
            static void Run1(object obj, bool sign)
            {
                Console.WriteLine("当前时间:{0}  我是线程{1}
    ", DateTime.Now, Thread.CurrentThread.ManagedThreadId);
            }
        }

    我们知道在Threading下面有一个Timer计时器,当定期触发任务的时候都是由线程池提供并给予执行,那么这里我们溶于信号量的概念以后同样可以实现计时器的功能。

        class Program
        {
            static void Main(string[] args)
            {
                AutoResetEvent ar = new AutoResetEvent(false);
                //参数2000:其实就是WaitOne(2000),采取超时机制
                ThreadPool.RegisterWaitForSingleObject(ar, Run1, null, 2000, false);
                Console.Read();
            }
    
            static void Run1(object obj, bool sign)
            {
                Console.WriteLine("当前时间:{0}  我是线程{1}
    ", DateTime.Now, Thread.CurrentThread.ManagedThreadId);
            }
        }

    有时候,跑着跑着我们需要在某个时刻停止它,没关系,RegisterWaitForSingleObject返回一个RegisteredWaitHandle类,那么我们就通过RegisteredWaitHandle来动态的控制,比如说停止计数器的运行。

        class Program
        {
            static void Main(string[] args)
            {
                RegisteredWaitHandle handle = null;
                AutoResetEvent ar = new AutoResetEvent(false);
                //参数2000:其实就是WaitOne(2000),采取超时机制
                handle = ThreadPool.RegisterWaitForSingleObject(ar, Run1, null, 2000, false);
                //10s
                Thread.Sleep(10000);
                handle.Unregister(ar);
                Console.WriteLine("干掉线程。");
                Console.Read();
            }
    
            static void Run1(object obj, bool sign)
            {
                Console.WriteLine("当前时间:{0}  我是线程{1}
    ", DateTime.Now, Thread.CurrentThread.ManagedThreadId);
            }
        }

  • 相关阅读:
    通达OA 新旧两种数据库连接方式
    c++ 如何获取系统时间
    性能测试开源小工具——http_load介绍
    http_load安装与测试参数分析
    不错的C++框架: Thrift(2)-传输和网络相关
    管理处理器的亲和性(affinity)
    300元内,此耳机是首选。不亏千人好评,对的起你的耳朵。
    [品质生活] 舒适 Schick HYDRO 5剃须刀
    巴氏刷牙法_百度百科
    Amazon.com : The Odyssey of the Manual Toothbrusher
  • 原文地址:https://www.cnblogs.com/lgxlsm/p/7552294.html
Copyright © 2011-2022 走看看