进程与线程
Process类常用属性和方法
Basepriority 进程优先级(只读) Priortyclass 设置或更改进程优先级 ExitCode 获取关联进程终止时指定的值 一般为0表 明进程成功退出 ExitTime 退出时间 HasExited 是否已终止 Id 进程唯一的标示符 MachineName 进程所运行的计算机名(本机名: Environment.machinename)
线程同步
• 当多个线程要对同一资源进行访问时,会出现如下问题: • 线程1在操作变量1,但线程1对变量1的操作没完成时,线 程1执行的时间已到,执行权交给线程2,此时线程2读取 变量1时读取的就是未知或者错误的数据。 • 要解决这一问题,.NET提供了很多方法,最简单的还是 lock • Lock’可以锁定某一变量,使得锁定范围内的代码期间只 能被一个单一线程操作(进入),操作完成后,其他线程 才可以进入执行。 • Demo 使用Lock实现线程同步 一个经典的多人同时提款 问题
• Demo:在线程池中执行任务
BackGroundWorker组建
• 当某些代码或者任务耗时比较长时,我们需要将 这些任务放在线程内执行,以避免影响主线程与 用户的交互。 • 这些工作用线程即可以实现,但在.NET中提供了 一个BackGroundWorker组件,专门用于完成这 些需要在后台线程内执行的工作,并可以通知主 线程任务进度及发送任务完成的消息。 • BackGroundWorker可以通过编程创建,也可以 通过工具箱拖放创建。
• GetProcessById 通过ID获取对应进程 • GetProcesses 获取本机所有进程 • Start 启动一个新进程
• DEMO 进程管理 启动和停止进程
线程
• System.threading下的Thread类,用于对线 程进行管理。 • Thread类方法和属性 • IsAlive • IsBackGround • IsThreadPoolThread • Priority • Join Start Sleep Abort
• StandardInput 获取用于写入应用程序输入 的流 • Standardoutput 获取应用程序输出的流 • Close • CloseMainWindow 向进程主窗口发送关闭 消息来管理具有用户界面的进程 • Kill 强制管理 • WaitForExit 设置等待关联进程退出的时间
前台线程和后台线程
• 一个线程要么是前台线程要么是后台线程, 两种线程基本是一样的,区别是后台线程 不会影响进程终止,当属于某个进程的所 有前台线程都终止后,公共语言运行库就 会结束该进程,而且属于该进程的后台线 程也都会停止运行,而不管后台工作是否 完成。
线程管理
• • • • • • • 启动线程 Thread th=new Thread(方法名); th.Start(参数); 停止线程 Th.Abort(); 暂停线程 Th.sleep(暂停时间);
• MainModule 关联进程的主模块(DLL EXE) • ProcessName 进程名称 • Startinfo 设置或获取要传递给进程的文件 名及启动参数 • StartTime • Threads 获取在进程中运行的一组线程 • WorkingSet64 物理内存 • PeakWorkSet64 使用的最大物理内存
• • • • •
BackGroundWorker方法和属性 ReportProcess 引发ProcessChanged事件 RunWorkAsync 开始执行后台操作 DoWork事件 调用RunWorkAsync时发生 RunWorkComplete 当后台操作完成、被取 消或者异常时发生 • Demo: BackGroundWorker使用
线程池
• 线程池是在后台执行多个任务的线程集合。 • 线程池的主要作用是限制同一时间内创建 的线程数量。 • 线程队列 先到先执行 • 每一个进程都有一个线程池,一般允许最 多25个线程存在。 • 所有线程池内的线程都是后台线程,也就 是会所不会影响主线程的结束。
• System.Threading.ThreadPool • ThreedPool常用方法 • GetAvailableThreads 检索线程池最大数目和当前 活动线程的差值 • GetMaxThreads 检索可以同时处于活动状态的线 程池请求的数目 • GetMinThreads 维护的空闲线程数目 • SetMaxThreads SetMinThreads • QeueUserWorkItem 将方法排入队列以便执行
第二章 进程与线程
进程与线程的概念
• 从概念上: 进程:一个程序对一个数据集的动态执行过 程,是分配资源的基本单位。 线程:一个进程内的基本 调度单位。 线程的划分尺度小于进程,一个进程包含一 个或者更多的线程。 • 从执行过程中来看: 进程:拥有独立的内存单元,而多 个线程共享内存,从而提高了应用程序的运行效率。 线 程:每一个独立的线程,都有一个程序运行的入口、顺序 执行序列、和程序的出口。但是线程不能够独立的执行, 必须依存在应用程序中,由应用程序提供多个线程执行控 制。 • 从逻辑角度来看:(重要区别) 多线程的意义在于一个 应用程序中,有多个执行部分可以同时执行。但是,操作 系统并没有将多个线程看做多个独立的应用,来实现进程 的调度和管理及资源分配。
• • • • • • •
合并线程 Thread th2=new Thread(); Th2.start(); ……. Public method(){…th2.join()…} Thread th1=new Thread(method); Th1.start();
Volatile关键字
• Volatile 字面的意思时易变的,不稳定的。在C#中也差不 多可以这样理解。 • 编译器在优化代码时,可能会把经常用到的代码存在 Cache里面,然后下一次调用就直接读取Cache而不是内 存,这样就大大提高了效率。但是问题也随之而来了。 • 在多线程程序中,如果把一个变量放入Cache后,又有其 他线程改变了变量的值,那么本线程是无法知道这个变化 的。它可能会直接读Cache里的数据。但是很不幸, Cache里的数据已经过期了,读出来的是不合时宜的脏数 据。这时就会出现bug。 • 用Volatile声明变量可以解决这个问题。用Volatile声明的 变量就相当于告诉编译器,我不要把这个变量写Cache, 因为这个变量是可能发生改变的。
• 在网络编程中,通常要使用多线程的概念 • 考虑在C/S的模式下,服务器端需要同时监 听或者处理多个客户端的请求,如果单线 程的话,在同一时间内,只有一个客户端 的清楚可以被处理。 • 另外当需要执行一些长时间任务或者等待 相应的时候也可以使用多线程技术。
C#进程管理
• 在System.Diagnostics命名控件下,有一个 Process类,用于完成与进程相关的处理任 务。 • 一个应用程序执行或者调用其他的应用程 序,实际上就是对进程进行管理。 • 比如常见的VSTO应用程序。
Demo:跨线程就不再允许在线程内访问 其他线程内的控件,如果要访问,需要使 用委托来实现。 • Demo:跨线程访问控件 • 通过例子可以看出两个具有相同优先级的 线程同时执行时,可以看做是同步的。
线程同步和线程池
• 多个线程同时运行,可能会因为线程之间 的逻辑关系而决定谁先执行谁后执行,这 就是线程同步。 • 由于内存有限,我们不可能让系统无限制 的创建大量线程,为了解决资源和效率问 题,引入了线程池的概念。