Download presentation
Presentation is loading. Please wait.
Published bySusanto Kusumo Modified 5年之前
2
$16 进程和线程
3
进程
4
进程 属性 ProcessName / Id MachineName / MainModule BasePriority
StartTime / ExitTime TotalProcessorTime / UserProcessorTime PrivateMemorySize64 / VirtualMemorySize64 PagedMemorySize64 / NonpagedMemorySize64
5
进程 操作 Start Kill CloseMainWindow Close
6
进程示例 //程序清单P16_1.cs: using System; using System.Diagnostics;
namespace P16_1 { class ProcessInfoSample static void Main() Process proc = Process.GetCurrentProcess(); OutputProcessInfo(proc); proc = Process.Start("Notepad.exe"); proc.WaitForExit(500); proc.WaitForExit(); } public static void OutputProcessInfo(Process p) { Console.WriteLine("进程{0} ID{1}:", p.ProcessName, p.Id); Console.WriteLine("启动时间" + p.StartTime); Console.WriteLine("基本优先级" + p.BasePriority); Console.WriteLine("专用内存{0}K", p.PrivateMemorySize64 / 1024); Console.WriteLine("使用物理内存{0}K", p.WorkingSet64 / 1024); Console.WriteLine("使用虚拟内存{0}K", p.VirtualMemorySize64 / 1024); Console.WriteLine("使用分页内存{0}K", p.PagedMemorySize64 / 1024); Console.WriteLine("使用非分页内存{0}K\r\n", p.NonpagedSystemMemorySize64 / 1024); }
7
线程
8
线程概念 每个进程启动时都将创建一个默认线程,称为进程的“主线程”。
执行过程中始终只有一个线程的程序,称为“单线程程序”,否则称之为“多线程程序”。 每个线程都可以创建新的线程,而主线程之外的其他线程都称为“辅助线程”。
9
线程属性 Name Priority IsAlive / IsBackGround ThreadState
10
线程简单示例 //程序清单P16_3.cs: using System; using System.Threading;
namespace P16_3 { class MultiThreadsSample private static Thread t1, t2; static void Main() Console.WriteLine("主方法开始"); t1 = new Thread(new ThreadStart(Method1)); t2 = new Thread(new ThreadStart(Method2)); t1.Start(); t2.Start(); Console.WriteLine("主方法结束"); } public static void Method1() { Console.WriteLine("线程1开始"); for (int i = 0; i < 100; i++) Console.WriteLine("线程1: " + i); Thread.Sleep(1); } Console.WriteLine("线程1结束"); public static void Method2() Console.WriteLine("线程2开始"); //if(t1.IsAlive) //t1.Join(); for (int i = 100; i >= 0; i -= 2) Console.WriteLine("线程2: " + i); Console.WriteLine("线程2结束");
11
线程应用场合 长时间等待:某些任务的执行可能需要较长的时间,这对于单线程程序就会出现阻塞甚至停止响应的情况,可以考虑使用多线程来提高程序的执行效率。 后台处理:对于图形界面应用程序来说,可以使用主线程来处理用户操作,而以辅助线程的方式在后台处理其他任务(如拼写检查,定时自动保存文件等),从而提高界面的友好性。 优先任务:有时候不同任务的执行顺序无关紧要或难以确定,但希望程序按照任务的轻重缓急程度来执行相应的代码,这就可以通过创建多线程以及设置线程的不同优先级来实现。
12
线程状态 Unstarted – 尚未启动 Running – 正在运行 Suspended – 已挂起
SuspendedRequested – 正在请求挂起 Aborted – 已终止 AbortRequested – 正在请求终止 WaitSleepJoin - 在等待 Background – 在后台运行 Stopped - 已停止 StoppedRequested – 正在请求停止
13
线程操作 Start – 启动线程 Abort – 终止线程 Interrupt – 中断处于等待状态的线程
Join – 合并线程并等待其执行完毕
14
线程操作示例 catch (ThreadAbortException) {
//程序清单P16_5.cs: using System; using System.Threading; namespace P16_5 { class ThreadAbortSample static void Main() int count = 0; Thread[] ts = new Thread[4]; for (int i = 0; i < 4; i++) ts[i] = new Thread(delegate() try Console.WriteLine("{0}开始于{1}", Thread.CurrentThread.Name, count); for (int j = 0; j < 100; j++) Console.WriteLine("{0}: {1}", Thread.CurrentThread.Name, count++); Thread.Sleep(1); } Console.WriteLine("{0}退出于{1}", Thread.CurrentThread.Name, count); catch (ThreadAbortException) { Console.WriteLine("{0}中止于{1}", Thread.CurrentThread.Name, count); } }); ts[i].Name = "线程" + i; ts[i].Start(); Thread.Sleep(10); ts[3].Abort(); ts[2].Abort(); ts[1].Join(); ts[0].Join(); Console.WriteLine("所有线程执行完毕");
15
线程同步同步 线程同步带来的问题 两个线程使用同一个循环变量,一个在循环中增加变量的值,另一个则减少变量的值,就可能导致两个线程都处于死循环的状态。 在银行应用程序中,一个账户可以开设多张银行卡,那么代表不同银行卡的两个线程可能同时查询到帐户余额为1000元,而后各自从帐户上取出800元,这就破坏了银行的业务规则。
16
线程同步问题示例 //程序清单P16_6.cs: using System; using System.Threading;
using System.Runtime.Remoting.Contexts; namespace P16_6 { class ThreadSynchronizationSample static void Main() TicketAgency ta = new TicketAgency(); Thread[] ts = new Thread[4]; for (int i = 0; i < 4; i++) ts[i] = new Thread(new ThreadStart(ta.RandomSell)); ts[i].Name = "窗口" + i; ts[i].Start(); }
17
线程同步问题示例 //[Synchronization()]
public class TicketAgency //: ContextBoundObject { private Mutex mut = new Mutex(); private int m_num = 0; private Random rand = new Random(); public void Sell() //mut.WaitOne(); //Monitor.Enter(this); //lock (this) if (m_num < 66) //int tmp = Interlocked.Increment(ref m_num); int tmp = m_num + 1; Thread.Sleep(1); //模拟售票过程所花费的时间 m_num = tmp; Console.WriteLine("{0}:售出{1}号车票", Thread.CurrentThread.Name, tmp); }
18
线程同步问题示例 else { Console.WriteLine("{0}:车票已售罄", Thread.CurrentThread.Name); } //Monitor.Exit(this); //mut.ReleaseMutex(); public void RandomSell() int time = rand.Next(20); for (int i = 0; i < 20; i++) Thread.Sleep(time); this.Sell();
19
线程同步问题解决 Lock – 简单锁 P385 Monitor – 监视器 P386 Mutex – 互斥对象 P387
Synchronization – 上下文同步 P388 Interlocked – 互锁操作 P388
20
线程回调 BeginRead IAsyncResult EndRead(IAsyncResult) Demo
21
线程回调示例 //程序清单P16_7.cs: using System; using System.Text;
using System.IO; using System.Threading; namespace P16_7 { class AsynIOSample static void Main() FileStream fs1 = new FileStream("C:\\Windows\\setuplog.txt", FileMode.Open, FileAccess.Read); byte[] bs = new byte[20000]; //fs1.Read(bs, 0, 20000); IAsyncResult ar = fs1.BeginRead(bs, 0, 20000, null, null); long pos1 = fs1.Position; StringBuilder sb1 = new StringBuilder(); for (int i = 0; i < 100; i++) sb1.Append((char)i); long pos2 = fs1.Position; fs1.EndRead(ar); long pos3 = fs1.Position; fs1.Close(); Console.WriteLine("开始生成字符串:{0}", pos1); Console.WriteLine("结束生成字符串:{0}", pos2); Console.WriteLine("结束文件读取:{0}", pos3); }
Similar presentations