多线程
因为web application做的比较多,所以多线程方面的知识很欠缺。最近被打击了,狠下心来恶补一下。一步一步来,在这里记个脚印吧,自己以后也可以看看。主要写给自己以后看的,就不装大师了,很多概念就不详细解释了。
1.线程和进程
怎么说呢,我自己的理解是线程是指对cpu说的,进程是跟内存有关的。一个进程里面可能有多个线程。比如一个ie8(及以前版本)浏览器,打开很多个tab,任务管理器里面只显示进程,但是至少一个tab是由一个线程管理的。
所以这就引出了多线程。
2.多线程
顾名思义,就是多个线程同时工作。现在的cpu都双核甚至多核的,所以多线程程序更能体现出多核的优势。
2.1 传统方式
以前,线程是通过Thread类来操作的,namespace System.Threading中 .先写个例子,直观的感觉下。
basic
2.2 较新方式
随着.net framework的升级,多线程变得越来越简单,好用。在.net4.0中,多了很多新的使用多线程的方式。通过 System.Threading.Tasks.Parallel and System.Threading.Tasks.Task classes, Parallel LINQ (PLINQ), 我们使用多线程的难度简化了。也举个TPL(task paralell library)并行例子吧。
以前,我们循环一个list中数据项时候
这样就 很花时间,因为是一个一个执行的。
如果使用并行的方式
Lst.AsParallel().ForAll(x => (x.Start(ExpensiveFunction));
这样一句就可以了,如果是多核的计算机,并行的方式极有可能提高效率的。但是如果我们只是一个非常简单的计算,就不必了
比如 ,num % 2实在是非常快速的操作,似乎就没有那么必要的去并行了
// Parallel equivalent Parallel.ForEach(sourceCollection, item => yeild return item % 2));
再举个PLINQ的例子。(PLINQ就是LINQ的并行方式)
var result = list.where(item=>item<100).select(n=>Fabtorial(n))//Fabtorial(N)求N阶层//顺序的方式运行
改成并行的方式,我们只需要简单的加上AsParalell()
var result=list.AsParalell().where(x=>x<100).select(n=>Fabtorial(n))
这里和TPL一样,只有当每个select条件都是比较花费时间的时候才时候用PLINQ,否则你就是会欲速则不达了。
3.TreadPool
用Tread类操作线程,还是比较麻烦的事情,TheradPool则省心些,ThreadPool会自己对线程进行管理,比如你不需要自己去process.Start(),他们自己会启动,并且据说,效率较高。
例子://ThreadPool demo public class ThreadPoolDemo {// Wrapper method for use with thread pool. public void ThreadPoolCallback(object threadContext) { int threadIndex = (int)threadContext; Console.WriteLine("thread {0} started...", threadIndex); Thread.Sleep(100); Console.WriteLine("thread {0} finished...", threadIndex); } }
在main中
static void Main(string[] args)
{
const int FibonacciCalculations = 10; Console.WriteLine("launching {0} tasks...", FibonacciCalculations); for (int i = 0; i < FibonacciCalculations; i++) { ThreadPool.QueueUserWorkItem(new ThreadPoolDemo().ThreadPoolCallback,i); }
ThreadPool使用很简单,主要的方法是QueueUserWorkItem,它的缺点同样明显,因为是统一管理,你自己就没有办法去管理某一个Thread的运行、优先级等等,而Thread是可以做到的。
4.Thread的优先级
Thread优先级是个枚举变量,共五个,ThreadPriority.Highest,ThreadPriority.AboveNomal, ThreadPriority.Nomal, ThreadPriority.belowNamal,ThreadPriority.Lowest。默认是Nomal
当有多个线程时候,级别高的先占据cpu资源,优先执行。
当一个低级别的线程正在执行时候,很可能被高级别的线程抢占,等高级别执行完后才接着执行
注意一点的是,系统给线程分配执行的最小时间片内,一个低级的线程必须执行完后才会被抢占,所以说也不是低级的线程立刻被抢占,必须是它当前最小时间片内完成后才会被抢占。例子:
}
main()
{
Thread t1 = new Thread(PriorityTest);
t2.Start();
}
如果是单核的计算机,执行的结果应该类似于
t1 worker thread reach 0
t2 worker thread reach 0
t2 worker thread reach 1
....
t2 worker thread reach 9
t1 worker thread reach 1...
但是当前的计算机基本都是多核的,所以可能会不是完全这样的顺序,但应该是t2先执行完,t1后
浙公网安备 33010602011771号