在"线程系列04,传递数据给线程,线程命名,线程异常处理,线程池"中,我们已经知道,每个进程都有一个线程池。可以通过TPL,ThreadPool.QueueUserWorkItem,委托与线程池交互。本篇体验:通过查看CLR代码来观察线程池及其线程。

□ 通过编码查看线程池和线程

使用ThreadPool的静态方法QueueUserWorkItem把线程放入线程池,来看线程池线程和主程序线程的执行情况。

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("主线程开始");
            for (int i = 0; i < 5; i++)
            {
                ThreadPool.QueueUserWorkItem(SayHello, i);
            }
            Console.WriteLine("主线程结束");
        }

        static void SayHello(object arg)
        {
            int n = (int) arg;
            Console.WriteLine("线程{0}接收到的参数是:{1},是否是后台线程:{2}",
                Thread.CurrentThread.ManagedThreadId,
                n,
                Thread.CurrentThread.IsBackground);
        }
    }


○ 用QueueUserWorkItem方法加入线程池的线程是后台线程
○ 一旦主线程结束,后台线程随即结束
○ 在主程序for语句块中,有2个线程已被创建并执行

让主线程和线程池线程都Sleep一段时间。

   class Program
    {
        static Random r = new Random();
        static void Main(string[] args)
        {
            Console.WriteLine("主线程开始");
            for (int i = 0; i < 5; i++)
            {
                ThreadPool.QueueUserWorkItem(SayHello, i);
            }
            Thread.Sleep(r.Next(250, 500));
            Console.WriteLine("主线程结束");
        }

        static void SayHello(object arg)
        {
            Thread.Sleep(r.Next(250, 500));
            int n = (int) arg;
            Console.WriteLine("线程{0}接收到的参数是:{1},是否是后台线程:{2}",
                Thread.CurrentThread.ManagedThreadId,
                n,
                Thread.CurrentThread.IsBackground);
        }
    }


○ 线程池中的线程依然是后台线程
○ 让主线程Sleep一段时间后,线程池的线程在主线程结束之前得以执行

再让主线程Sleep更长的一段时间。

        static void Main(string[] args)
        {
            Console.WriteLine("主线程开始");
            for (int i = 0; i < 5; i++)
            {
                ThreadPool.QueueUserWorkItem(SayHello, i);
            }
            Thread.Sleep(r.Next(1000, 3000));
            Console.WriteLine("主线程结束");
        }

当主线程Sleep的时间更长后,线程池有更多的线程被执行。

□ 使用"即时窗口"查看CLR中的线程池和线程

以上,通过编码查看线程池和线程,实在是太不方便。我们可以在"即时窗口"中,借助"SOS调试扩展"来观察CLR中的线程池和线程。

→在"Thread.Sleep(r.Next(1000, 3000))"打上断点
→点击"启动"
→当代码运行到断点处,点击"调试"--"窗口"--"即时",打开"即时窗口"
→输入如下命令,加载"SOS调试扩展"

关于"SOS调试扩展"的使用,可参考"调试查看CLR运行代码"。
→输入如下命令,查看线程池

○ Worker Thread显示当前线程池中的线程状况
○ Work Request in Queue显示当前队列中的线程
→输入如下命令,查看所有线程

○ MTA (Finalizer)表示由GC回收的线程
○ MTA (Threadpool Worker) 表示线程池中的线程

□ 查看CLR托管堆上的所有线程类型

→输入如下命令查看CLR托管堆上的所有线程类型

□ 查看CLR托管堆上线程池实例

→找到System.ThreadPoolWorkQueue,复制其前面的MT代码
→输入如下命令,查看线程池实例的堆地址、数量等

□ 查看CLR托管线程池地址

→复制System.Threading.ThreadPoolWorkQueue的托管堆地址
→输入如下命令查看CLR托管线程池地址内容

线程系列包括:

线程系列01,前台线程,后台线程,线程同步

线程系列02,多个线程同时处理一个耗时较长的任务以节省时间

线程系列03,多线程共享数据,多线程不共享数据

线程系列04,传递数据给线程,线程命名,线程异常处理,线程池

线程系列05,手动结束线程

线程系列06,通过CLR代码查看线程池及其线程

线程系列07,使用lock语句块或Interlocked类型方法保证自增变量的数据同步

线程系列08,实现线程锁的各种方式,使用lock,Montor,Mutex,Semaphore以及线程死锁

线程系列09,线程的等待、通知,以及手动控制线程数量

线程系列10,无需显式调用线程的情形

线程系列06,通过CLR代码查看线程池及其线程的更多相关文章

  1. 线程系列08,实现线程锁的各种方式,使用lock,Montor,Mutex,Semaphore以及线程死锁

    当涉及到多线程共享数据,需要数据同步的时候,就可以考虑使用线程锁了.本篇体验线程锁的各种用法以及线程死锁.主要包括: ※ 使用lock处理数据同步※ 使用Monitor.Enter和Monitor.E ...

  2. 线程系列07,使用lock语句块或Interlocked类型方法保证自增变量的数据同步

    假设多个线程共享一个静态变量,如果让每个线程都执行相同的方法每次让静态变量自增1,这样的做法线程安全吗?能保证自增变量数据同步吗?本篇体验使用lock语句块和Interlocked类型方法保证自增变量 ...

  3. 7种创建线程方式,你知道几种?线程系列Thread(一)

    前言 最近特别忙,博客就此荒芜,博主秉着哪里不熟悉就开始学习哪里的精神一直在分享着,有着扎实的基础才能写出茁壮的代码,有可能实现的逻辑有多种,但是心中必须有要有底哪个更适合,用着更好,否则则说明我们对 ...

  4. ReentrantLock+线程池+同步+线程锁

    1.并发编程三要素? 1)原子性 原子性指的是一个或者多个操作,要么全部执行并且在执行的过程中不被其他操作打断,要么就全部都不执行. 2)可见性 可见性指多个线程操作一个共享变量时,其中一个线程对变量 ...

  5. 第三十八天 GIL 进程池与线程池

    今日内容: 1.GIL 全局解释器锁 2.Cpython解释器并发效率验证 3.线程互斥锁和GIL对比 4.进程池与线程池 一.全局解释器锁 1.GIL:全局解释器锁 GIL本质就是一把互斥锁,是夹在 ...

  6. GIL锁、进程池与线程池

    1.什么是GIL? 官方解释: ''' In CPython, the global interpreter lock, or GIL, is a mutex that prevents multip ...

  7. C# 多线程学习系列三之CLR线程池系列之ThreadPool

    一.CLR线程池 1.进程和CLR的关系一个进程可以只包含一个CLR,也可以包含多个CLR2.CLR和AppDomain的关系一个CLR可以包含多个AppDomain3.CLR和线程池的关系一个CLR ...

  8. [Sciter系列] MFC下的Sciter–5.Sciter中GUI线程研究

    [Sciter系列] MFC下的Sciter–5.Sciter中GUI线程研究,目前MFC存在问题,win32没问题. 本系列文章的目的就是一步步构建出一个功能可用,接口基本完善的基于MFC框架的Sc ...

  9. 转:C#线程系列讲座(1) BeginInvoke和EndInvoke方法

    转载自:http://www.cnblogs.com/levin9/articles/2319248.html 开发语言:C#3.0IDE:Visual Studio 2008本系列教程主要包括如下内 ...

随机推荐

  1. 在SQL2008和2012里面怎么让显示全部行和编辑 全部而不是200和1000

    在sql server2008里面,可能微软考虑到数据量比较大,如果直接返回所有行,可能造成耗费时间过多.所有默认为"编辑前200行"和"返回前1000行".这 ...

  2. Tensorflow之训练MNIST(1)

    先说我遇到的一个坑,在下载MNIST训练数据的时候,代码报错: urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FA ...

  3. progressDialog和子线程模拟显示拷贝进度

    package com.example.wang.myapplication; import android.app.ProgressDialog; import android.os.Bundle; ...

  4. 关于《C++ Templates》

    最近买了<C++ Templates>来看,书最开始部分阐述了关于此书的一些编程风格.本人感觉非常好,有些地方之前一直容易搞混,这里却讲述的很清楚.例如: 关于下面几种风格的代码: voi ...

  5. WangSql 3.0源码共享(WangSql 1.0重大升级到3.0)

    WangSql 1.0博文阅读: http://www.cnblogs.com/deeround/p/6204610.html 基于1.0做了以下重大改动: 1.多数据实现方式调整 2.使用EmitM ...

  6. 深入理解SQL的四种连接,左外连接,右外连接,内连接,全连接

    1.内联接(典型的联接运算,使用像 =  或 <> 之类的比较运算符).包括相等联接和自然联接.     内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行.例如,检索 stude ...

  7. C#剪切板

    C#剪切板 Clipboard类 我们现在先来看一下官方文档的介绍 位于:System.Windows.Forms 命名空间下 Provides methods to place data on an ...

  8. python 对字典"排序"

    对字典进行排序?这其实是一个伪命题,搞清楚python字典的定义---字典本身默认以key的字符顺序输出显示---就像我们用的真实的字典一样,按照abcd字母的顺序排列,并且本质上各自没有先后关系,是 ...

  9. opencv 掩膜操作 滤波 卷积核定义 增强对比度 掩膜运算

    /* 矩阵的掩膜操作 0 掩膜mask 在这里进行增强对比度: [ [ 0,-1, 0 ], [-1, 5, -1], [ 0,-1, 0 ] ] 使用mask滑动图片每一个位置,进行卷积运算 这里这 ...

  10. php缓存类 内置output_buffer(ob)

    <?php class Cache { /** * $dir : 缓存文件存放目录 * $lifetime : 缓存文件有效期,单位为秒 * $cacheid : 缓存文件路径,包含文件名 * ...