多线程编程的基本概念
1 请解释操作系统层面上的线程和进程
2 多线程程序在操作系统里是并行执行的吗
3 什么是纤程
.NET中的多线程
1 如何在.NET程序中手动控制多个线程
2 如何使用.NET的线程池
3 如何查看和设置线程池的上下文
4 如何定义线程独享的全局数据
5 如何使用异步模式读取一个文件
6 如何阻止线程执行上下文的传递
多线程程序的线程同步
1 什么是同步块和同步块索引
2 C#中的lock关键字有何作用
3 可否使用值类型对象来实现线程同步
4 可否对引用类型对象自身进行同步
5 什么是互斥体,Mutex类型和Monitor类型的功能有何区别
进程的概念
进程代表操作系统上运行着的一个应用程序。进程拥有自己的程序块,拥有独占的资源和数据,并且可以被操作系统来调度。即使同一个应用程序,当被强制多次启动时,也会被安装在不同的进程中单独运行。通过进程浏览器可以查看计算机真正运行的进程。但并不是每个进程都会在Windows自带的进程浏览器中显示。
线程的概念
线程是一个可以被调度的单元,并且维护自己的堆栈和上下文。线程是附属于进程的,一个进程可以包含一个或者多个线程,并且同一进程内的多个线程共享一块内存和资源。一个线程是一个操作系统看调度的基本单元,但同时它的调度受限于包含线程的进程,也就是说操作系统首先决定下一个执行的进程,进而才调度该进程内的线程。
线程和进程的区别
线程和进程最大的区别在于隔离性问题。每个进程都被单独地隔离,拥有自己的内存块、独占的资源及运行数据,一个进程的崩溃不会影响到其他进程,而进程之间的交互也是相当困难的。和进程不同,同一进程内的所有线程共享资源和内存块,并且一个线程可以访问、结束同一进程内的其他线程。
在单CPU的计算机架构上,任何时候只能存在一个运行的线程,操作系统通过快速地调度轮换使使用者感觉到多线程在同时运行。而在多CPU的架构上,则可能存在完全并行的线程,这取决于线程之间是否征用了其他的资源。
纤程是微软提出的最轻量级线程的概念,一个纤程拥有自己的栈和寄存器状态。一个线程可以包含多个纤程,和线程可以由操作系统调度有所不同的是,线程内纤程的调度完全由程序员自己调度,操作系统的内核完全不知道纤程的存在。在.NET中线程的概念不一定和操作系统中的线程对应,在有些情况下.NET中的线程对应一个纤程。
.NET提供了System.Threading.Thread类型封装了线程的操作,通过该类型,程序员可以手动地创建、查询、控制以及结束线程。
示例:
1 class ThreadState 2 { 3 static void Main(string[] args) 4 { 5 Console.WriteLine("开始测试线程1"); 6 7 //初始化一个线程 8 Thread thread1 = new Thread(Work1); 9 PrintState(thread1); 10 11 //启动线程 12 Console.WriteLine("现在启动线程"); 13 thread1.Start(); 14 PrintState(thread1); 15 //让线程运行一段时间 16 Thread.Sleep(3 * 1000); 17 18 //让线程挂起 19 Console.WriteLine("现在挂起线程"); 20 thread1.Suspend(); 21 //给线程足够的时间来挂起 22 //否则的话状态可能是SuspendRequested 23 Thread.Sleep(1000); 24 PrintState(thread1); 25 26 //继续线程 27 Console.WriteLine("现在继续线程"); 28 thread1.Resume(); 29 PrintState(thread1); 30 31 //停止线程 32 Console.WriteLine("现在停止线程"); 33 thread1.Abort(); 34 //给线程足够的时间来停止 35 //否则的话状态可能是AbortRequested 36 Thread.Sleep(1000); 37 PrintState(thread1); 38 39 Console.WriteLine("开始测试线程2"); 40 //初始化一个线程 41 Thread thread2 = new Thread(Work2); 42 PrintState(thread2); 43 44 //查看睡眠状态 45 thread2.Start(); 46 Thread.Sleep(2*1000); 47 PrintState(thread2); 48 49 //给线程足够的时间结束 50 Thread.Sleep(10 * 1000); 51 PrintState(thread2); 52 53 Console.Read(); 54 } 55 /// <summary> 56 /// 线程方法 57 /// </summary> 58 private static void Work1() 59 { 60 Console.WriteLine("线程运行中..."); 61 //模拟线程运行,但不改变线程状态 62 //采用忙等状态 63 while (true) ; 64 } 65 /// <summary> 66 /// 保证一个线程运行10秒就结束 67 /// </summary> 68 private static void Work2() 69 { 70 Console.WriteLine("线程开始睡眠"); 71 //睡眠10秒就结束 72 Thread.Sleep(10 * 1000); 73 Console.WriteLine("线程恢复运行"); 74 } 75 76 /// <summary> 77 /// 打印线程的状态 78 /// </summary> 79 /// <param name="thread"></param> 80 private static void PrintState(Thread thread) 81 { 82 Console.WriteLine("线程的状态是:{0}", 83 thread.ThreadState.ToString()); 84 } 85 }