[转载]Windows下如何高效多线程编程

1 必备知识:线程调度/上下文切换原理
Windows系统有一个线程调度功能,它以化整为0的形式分布在系统内核的各个角落.
系统每时每刻会发生各种事件(硬件中断,比如时钟中断),Windows系统内核在这时得到执行机会,进行线程调度工作(如果没有时钟中断,在单核cpu上,仅一个线程可以cpu被运行,如果用户线程占着cpu不放,操作系统将什么也作不了.).

Windows系统内核会遍历一个可调度线程小型库(有很多是不可调度的线程,不在这里.),通过特殊算法,找到下一个被执行的线程.

加载线程的信息到cpu寄存器(比如进程的地址空间,ip寄存器指令指针),然后执行线程的代码,Windows系统内核会在下一次中断事件重复上面步骤.

每一次进行线程切换时,都会浪费cpu周期与系统资源,所以减少线程切换是提升性能的关键.

2 轮询等待与sleep(xxx);
轮询是最浪费cpu资源的,也是使用最简单最方便的通信手段之一.
最差的轮询 while(!bCancel){ Thread.Sleep(x);} //这里的x值不为0的效果最好.
简单的使用事件通知替换效果会好一些,看看注释,我说明了原因.

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace ConsoleApplication1_TestThread
7 {
8 class Program
9 {
10 staticvoid Main(string[] args)
11 {
12 bool bCancel =false;
13
14 System.Threading.ManualResetEvent mre =new System.Threading.ManualResetEvent(false);
15 var t1 =new System.Threading.Thread(new System.Threading.ThreadStart(delegate()
16 {
17 System.Threading.Thread.Sleep(8000);//模拟用户8秒后点了取消按钮.
18 bCancel =true;
19 mre.Set(); //通知事件,被挂起的线程可以恢复调度,而且得到执行.
20 }));
21 t1.Start();
22
23 new System.Threading.Thread(new System.Threading.ThreadStart(delegate()
24 {
25 //打开某些资源进行操作.
26 if (!bCancel)
27 {
28 mre.WaitOne(); //线程被挂起,并且不可调度,系统不会再给它机会执行了,除非得到事件通知.
29 System.Console.WriteLine("用户取消.");
30 //关闭打开的资源,停止操作.
31 }
32 //while (!bCancel)
33 //{
34 // System.Threading.Thread.Sleep(2000); //虽然线程被挂起,但是2秒钟后系统还会切换到这里,那么就会发生多次线程切换,浪费cpu与系统的资源,而这些浪费是没有意义的可以省略的.
37 //}
38 //System.Console.WriteLine("用户取消.");
39
40 })).Start();
41
42 System.Console.Write("结束.");
43 System.Console.ReadKey();
44 }
45 }
46 }
posted @ 2011-12-08 10:43  zlalex  阅读(268)  评论(0编辑  收藏  举报