多线程初学
来源:互联网 发布:怎么购买淘宝小号 编辑:程序博客网 时间:2024/05/19 22:06
多线程的概念:
一个正在运行的程序就是一个进程,一个进程至少有一个线程,同一个进程中的多个线程之间可以“并发”执行。
线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。
多线程的优缺点:
多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务(代码),也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。这样可以提高CPU的利用率。在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,这样就大大提高了程序的效率。
而不利的地方就是多线程需要占用内存,线程越多占用的内存就越多。并发执行时控制太复杂,可能造成无法预料的BUG,而且竞争共享资源。
.net中如何实现多线程:
线程肯定也是要执行一段代码的。所有要产生一个线程,必须先为该线程写一个方法,这个方法中的代码就是该线程运行多要执行的代码。
线程启动时,通过委托调用该方法。
(线程启动时,调用传过来的委托,委托就会执行相应的方法,实现线程执行方法)
产生一个线程的4步骤:
编写产生线程所要执行的方法
引用System.Threading命名空间
实例化Thread类,并传入一个指向线程所要运行方法的委托(这时候这个线程已经产生,但是还没有运行)
调用Thread实例的Start方法,标记该线程可以被CPU执行了,但具体执行时间由CPU决定。
前台线程和后台线程:
前台线程:只有所有的前台线程都关闭才能完成程序关闭。
后台线程:只要所有的前台线程结束,后台线程自动结束。
程序中通过设置线程的IsBackground属性为true,将线程设置为后台线程。
下面为一个例子
public Form1() { InitializeComponent(); TextBox.CheckForIllegalCrossThreadCalls = false; } void Count999999999()//让计算机从0数到999999999,计算时间 { DateTime begin = DateTime.Now; for (int i = 0; i <= 999999999; i++) { } TimeSpan span = begin.Subtract(DateTime.Now); MessageBox.Show("走完了~"+span); } private void Btn_singlethread_Click(object sender, EventArgs e)//使用单线程计数 { Count999999999(); } private void Btn_multithreads_Click(object sender, EventArgs e)//使用多线程 { Thread multigo = new Thread(Count999999999);//创建多线程,并写入调用的函数 multigo.IsBackground = true;//讲多线程设为后台线程 multigo.Start();//启用多线程 }
这时可以看到,在单线程执行时,UI不能响应用户操作,而使用多线程时却可以。这是因为创建负责计数的线程替UI线程完成了计数功能,这样UI线程就能空出来完成自己的功能了。
为了说明多线程在同时执行时的不确定性,我们来引入下面一个例子,这个例子也是我在面试时遇到的一道题。
Thread THWriteab = null; Thread THWritecd = null; private void Btn_writeletter_Click(object sender, EventArgs e)//开始按钮 { THWriteab = new Thread(WriteAB); THWriteab.IsBackground = true; THWriteab.Start(); THWritecd = new Thread(Writecd); THWritecd.IsBackground = true; THWritecd.Start(); } public void WriteAB()//函数用来输出AB { while (true) { textBox1.AppendText("AB"); } } public void Writecd()//函数用来输出cd { while (true) { textBox1.AppendText("cd"); } } private void btnWriteStop_Click(object sender, EventArgs e)//停止进程的按钮 { THWriteab.Abort();//进程<span style="font-family:Arial,Helvetica,sans-serif">THWriteab停止</span> THWritecd.Abort();//进程<span style="font-family:Arial,Helvetica,sans-serif">THWritecd停止</span> }
造成这种情况的原因,是线程在执行过程中可能随时睡眠,并由CPU切换到下一进程继续执行。在本例中,可能刚输出一个A,然后线程睡眠,CPU跳到输出CD的进程中,在输出了CD之后又跳回输出B。(CPU在同一时间只能执行一个线程,多核CPU可以同时执行多个)
线程的同步策略:
当一个方法被应用程序中多个线程访问时,由于多个线程间的并发访问,会使调用方法后的结果不可预测。一种可行的线程同步策略是使用Monitor类和Lock关键字。
(1) Monitor类用于同步代码区,其思想是首先使用Monitor.Enter()方法获得一个锁,然后使用Monitor.Exit()方法释放该锁。一个线程一旦获得重要代码区的锁,其他线程就要等到该锁被释放后才能使用该代码区。代码如下:
public void ShowData1(string data) { Monitor.Enter(this); //加上monito锁 for (int i=0; i < 100; i++) //重要代码区 { Console.WriteLine(data); } Monitor.Exit(this); //施放monitor锁 }
(2) 使用Lock关键字同样可以获得一个Monitor锁。只需要简单的用lock语句将需要同步的代码括起来,括号表示受保护代码的起始点和终止点。代码如下:
public void ShowData2(string data) { lock (this) //lock语句 { for (int i = 0; i < 100; i++) //重要代码区 { Console.WriteLine(data); } Monitor.Exit(this); } }
- 初学多线程
- 多线程初学
- 多线程初学
- 多线程初学
- 初学多线程
- 多线程初学
- 初学java多线程
- [zt] 初学java多线程
- [zt] 初学java多线程
- 初学多线程编程
- 初学多线程有感
- vc++ 多线程编程(初学)
- Java多线程初学笔记
- 多线程 -- 初学简单例子
- Java 多线程初学
- 初学windows 下 多线程编程
- 初学多线程,求高手指点
- 初学Java多线程:线程简介
- win XP 不能访问无线wifi 补丁 Windows XP 更新程序 (KB893357)
- 利用自定义函数求四个数的最大公约数
- HDU 1973 BFS+素数打表
- PCM(44字节)的Wav文件头及其相关的编程方法
- [Sciter系列] MFC下的Sciter–3.Sciter脚本与底层交互
- 多线程初学
- [命令]
- Eclipse C/C++开发环境搭建
- 曾经汇编常用指令整理笔记
- 第一个opengl程序
- ADC 驱动实例开发
- 使用FindFirstFile,FindNextFile遍历一个文件夹
- 最小操作数递归实现
- 父进程啊父进程