VB2008 进程函数

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

进程和线程
2009-12-22 13:12
在.NET平台发布之前,“进程”的概念就已经存在于基于Windows的操作系统中。

简单来说,进程是一个术语,用于描述当前运行的应用程序使用的一组资源(如外部代码库和主线程)以及必要的内存分配。

对于加载到内存中的每个*.exe,OS创建单独的、隔离的进程,在其生命周期中使用该进程。

使用这种应用程序隔离的方法,就可以产生更为健壮的和稳定的运行库环境,前提是一个进程的失效不会影响另一个进程的机能。

现在,每个Windows都被分配一个唯一的进程标识符(Process Identifier,PID),该进程标识符可能由OS根据需要独立地加载和卸载。

使用Windows Task Manager(任务管理器)实用程序(通过Ctrl+Shift+Esc 按键组合激活)可以查看运行在给定机器上的进程的各种状态,包括该进程的PID和映像名。

图17-1显示了Windows Task Manager的Processes选项卡。

注意:
默认情况下,Processes选项卡的PID列不可见。

为了查看该列,可选择View | Select Columns菜单选项并选中PID(Process Identifier)复选框。

每个Windows进程都确切地有一个主“线程”,该线程的作用是应用程序的入口点。

第18章将介绍如何使用System.Threading名称空间创建额外的线程和线程安全代码;然而,为了帮助了解此处介绍的主题,我们需要提供一些有效的定义。

首先,线程是进程中的执行路径。

按照正式的说法,进程的入口点(Main()方法)创建的第一个线程称为主线程。

包含一个执行主线程的进程在本质上是线程安全的,因为给定时间内只有一个线程可以访问应用程序中的数据。

然而,如果唯一的线程正在执行复杂的操作(例如,输出很长的文本文件、执行包含大量数学操作的计算、或者尝试连接到位于数千英里远的远程服务器),单线程的应用程序(特别是基于GUI 的应用程序,例如Windows Forms应用程序)就可能显得对用户的响应不那么灵敏。

由于单线程应用程序具有这种潜在的缺陷,Windows操作系统允许主线程产生额外的辅助线程,该操作在过去涉及调用大量基于C的Win32 API函数,如CreateThread()。

每个线程(主线程或辅助线程)都成为进程中的独特执行路径,并且具有对所有共享数据点的当前访问。

开发人员通常创建额外的线程来帮助改进程序的整体响应灵敏度。

多线程的进程提供了大量活动差不多同时发生的假象。

例如,应用程序可能产生一个工作者线程来执行劳动密集的工作单位(如打印大型的文本文件)。

当这个辅助线程正在执行打印操作时,主线程仍然可以响应用户输入,这就为整个进程提供了提高性能的潜力。

然而,实际情况可能并不是如此:在某个进程中使用过多的线程实际上会降低性能,因为CPU必须在进程的活动线程之间切换(这需要花费一定的时间)。

实际上,多线程是OS提供的最常见的假象。

只有一个CPU的机器不能够同时确切地处理多个线程。

相反,基于线程的优先级别,单一的CPU在某个时间单位(称为时间片)内只执行一个线程。

当某个线程的时间片启动时,就会挂起已有的线程以允许另一个线程执行它的业务。

为了让线程记住在其被挂起之前所发生的情况,为每个线程提供了写入到线程本地存储器(Thread Local Storage,TLS)的能力,并且为其提供了单独的调用栈,如图
线程本地存储器(TLS)是由OS专门分配给每个线程的内存区域。

如果您才开始学习线程这个主题,并不需要深入研究细节此时,只需要记住线程是Windows进程中的独特执行路径。

每个进程都有一个主线程(通过可执行文件的Main()方法创建),并且可能包含已经通过编程方式创建的额外线程。

17.1.2 在.NET平台下与进程交互
虽然进程和线程并不是新内容,但是在.NET平台下与这些原始内容进行交互有很大的改动(为了更好地进行交互)。

接下来首先介绍如何使用.NET基类库与进程交互。

System.Diagnostics名称空间定义了大量用于以编程方式与进程交互的类型,并且定义了各种与诊断相关的类型,如系统事件日志和性能计数器。

本章中只介绍以进程为中心的类型,表17-1定义了这些类
型。

表17-1 重要的System.Diagnostics名称空间成员
使用System.Diagnostics.Process类型可以分析运行在给定机器(本地或远程)上的进程。

Process类也提供用于如下方面的成员:以编程方式启动和终止进程、建立进程的优先级、以及获得给定进程中的活动线程和/或已加载模块的列表。

表17-2列出了System.Diagnostics.Process的一些(但不是全部)关键成员。


17.1.3 列举运行的进程
为了举例说明操作Process类型的过程,假设有一个名为ProcessManipulator的VB 2008控制台应用程序,该应用程序在初始的Module中定义了如下方法(确保导入System.Diagnostics名称空间以用于代码文件中):
Public Sub ListAllRunningProcesses()
' Get all the processes on the local machine.
Dim runningProcs As Process() = Process.GetProcesses(".")
' Print out PID and name of each process.
For Each p As Process In runningProcs
Dim info As String = String.Format("-> PID: {0}" & _
Chr(9) & "Name: {1}", p.Id, p.ProcessName)
Console.WriteLine(info)
Next
Console.WriteLine("************************************")
Console.WriteLine()
End Sub
注意共享的Process.GetProcesses()方法如何返回Process类型的数组,该数组代表目标机器(显示在此处的点符号代表本地计算机)上运行的进程。

一旦获得Process类型的数组,就能够访问表17-2所列出的任何成员。

此处只是显示每个进程的PID和名称。

假设已经更新Main()方法以调用ListAllRunningProcesses(),就可以看到类似于图17-3所示的输出。

17.1.4 研究特定的进程
为了获得给定机器上所有运行进程的详尽而完整的列表,使用共享的Process.GetProcessById()方法可以通过相关的PID获得一个Process类型。

如果请求访问不存在的进程ID,就会抛出ArgumentException 异常。

例如,如果有兴趣获得代表PID为987的进程的Process对象,可以编写如下代码:
' If there is no process with the PID of 987, a
' runtime exception will be thrown.
Sub Main()
Console.WriteLine("***** Fun with Processes *****" & vbLf)
ListAllRunningProcesses()
' Look up a specific process.
Dim theProc As Process
Try
theProc = Process.GetProcessById(987) ' Manipulate the process handle...
Catch ' Generic catch used for simplicity. Console.WriteLine("-> Sorry...bad PID!") End Try
Console.ReadLine()
End Sub。

相关文档
最新文档