深入C#并行编程(1) -- 了解线程
一、操作系统用进程(processe)分隔正在执行的程序,用线程(thread)作为操作系统分配处理器时间的基本单元,进程上下文中可以运行多个线程,进程的所有线程共享其虚拟地址空间,所有线程均可执行程序代码中的任意部分,包括其他线程正在执行的代码;
1.默认情况下,.net程序只启动单个线程,被称为主线程(primary thread),也可以在运行时开启其它线程,与主线程并行同时执行代码,这些线程被称为工作线程(worker thread);由.net开启和管理的线程通常称为托管线程(managed thread);
2.托管线程又分为前台线程和后台线程,两者类似,但前台线程会阻止进程停止,而后台线程不会,即当进程的main方法结束后,只有在所有前台线程都停止时,clr才会结束该进程,此时会对仍处于活动状态的后台线程调用abort方法来结束所有后台进程;
※关闭程序如遇到无法关闭所有线程时,可以在main方法结束前通过以下代码强制关闭所有线程,详见:
system.environment.exit(0);
二、在使用多线程时,不同线程不仅可以同时执行同一段代码,还可以同时访问同一内存中的数据,所以会存在一定的数据冲突问题,称为争用条件(race condition):
static int mynum; static int raceconditioncount; static void myfunc() { while (true) { if (mynum == 0) { mynum++; if (mynum == 0) { raceconditioncount++; //只有在出现争用条件时才会执行此语句 } } mynum = 0; } } static void main(string[] args) { for (int i = 0; i < 2; i++) { thread thread = new thread(myfunc); thread.start(); } thread.sleep(1000); console.writeline(raceconditioncount); //输出1秒内产生争用条件的次数 console.read(); }
1.对于争用条件的发生频率,发布版本比调试版本的出现次数多(发布版本编译出的代码被优化过而且开启了jit优化),多核cpu比单核cpu的出现次数多(多核cpu中多个线程可以同时运行,单核cpu的线程调度是抢占式的,也会出现此问题,只是次数较少);
三、为了避免产生争用条件,需要注意数据的同步问题,可以通过给对象加锁,使同一时间内只有一个线程可以执行加锁对象所锁定的代码;
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的认可是我写作的最大动力!
作者:minotauros
出处:
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。