现在的位置: 首页 > 综合 > 正文

Visual Studio调试多线程应用程序

2018年06月07日 ⁄ 综合 ⁄ 共 2057字 ⁄ 字号 评论关闭

Visual Studio调试多线程应用程序

10.3.3 调试多线程应用程序

多线程应用程序是在给定的进程中有多于一个的线程在运行的应用程序。默认情况下,每个运行应用程序的进程有至少一个执行线程。你也许创建多个线程来做并行处理。这可以显著地提升性能,尤其在运行今天的多核处理器和超线程技术的时候。然而,多线程也带来了更大的开销。代码变得更加复杂难写且更难于调试。如果你曾写过多线程应用程序,你就知道了。

幸好,Visual studio提供若干工具,使得该工作稍微容易一些。我们不在这里介绍如何编写多线程应用程序。而是介绍调试多线程应用程序时可用的调试选项。以下列出这些工具和特性。

调试会话期间在源代码中查看线程;

用于查看进程、线程和标记的线程的Debug Location工具栏;

用于处理应用程序中线程列表的Thread窗口;

允许你为单独线程设置断点的断点过滤器。

让我们更详细地看一下这些特性中的每一项。

1. 发现和标记线程

Visual Studio允许你在应用程序的调试模式中可视化线程。当停在断点的时候,应用程序会被暂停,你可以调试活动的线程。在这个时候,应用程序中的其他线程仍然存在。然而,它们也许不可见。要在调试菜单中看到它们,可以使用来自Debug菜单的Show Threads in Soure(在源代码中显示线程)选项,如图10-37所示。

选择该选项将突出显示在代码中存在的其他线程。调试会话期间,这些代码行将为你突出显示在代码窗口的指示器空白边缘。用于突出显示这些项的图标看起来像两条波浪线(或者装饰线)。图10-38给出了一个示例。

 
图10-37 在Source(源代码)
选项中显示/隐藏线程
 
图10-38 在指示器空白边缘处突出显示的线程

注意,第29行左侧的图像。它表示在你源代码中该位置存在线程。鼠标悬停在这个指示器会显示该指示器所引用的线程(或多条线程)。每条线程由它的ID号(在方括号中)和名称(如果有的话)表示。图10-39给出了一个示例。

提示 命名线程有助于你在调试的时候更好地识别它们。要命名一条线程,可以使用Threading命名空间。具体来说,调用Thread类的Name属性。

既然你已经找到了一条线程,你也许会想要标记它以便进一步监控。这样仅有助于把你要监控的和你不关心的线程进行分组。你可以在指示器空白边缘右侧标记一条线程。右击该指示器并在上下文菜单中选择Flag(标记)选项可完成此操作。图10-40给出了一个示例。

 
图10-39 在线程指示器上悬停
 
图10-40 标志一条线程

同样你可以取消标记线程。你也可以在Tbread窗口直接标记线程。标记的线程在Tbread窗口和Debug Location工具栏中提供了特殊的分组。接下来我们将介绍这些特性。

2. 管理调试进程和线程

你可以使用Debug Location工具栏在正被调试的进程和这些进程中的线程之间进行切换。这个工具栏如图10-41所示。左侧是Process列表。这里你可以选择一个进程来查看关于该进程的详细信息,包括正在执行的线程。但是,许多多线程应用程序都在单个进程中运行。

 
(点击查看大图)图10-41 Debug Location工具栏

工具栏上的Thread列表显示了所选进程的线程的列表。这个列表在图10-41中被突出显示。注意,线程和它们的ID、名称和标记指示器一起显示。你可以在这个列表中选择一条线程来跳转到和该线程相关的源代码。如果没有与所选线程相关的源代码,该线程名在选中时将以红色显示。你可以通过切换Thread列表(显示带有两个标记)右边的第二个按钮过滤这个列表,从而仅显示标记的线程。右边第一个按钮仅标记(或取消标记)当前的活动线程。最后,右侧的列表显示调用栈。调用栈中的活动栈帧就是在调试窗口(监视窗口、局部窗口、自动窗口等)中显示的部分。

你也可以在Threads窗口(Debug菜单、Windows、Threads)里管理线程。这里你将看到所有为给定的进程列出的线程。图10-42给出了一个示例。注意,该列表的左侧显示了标记的线程。这里我们有示例应用程序中两个标记的线程。还要注意到这些线程已经命名,这样在Name栏中易于识别。

 
(点击查看大图)图10-42 Threads窗口

Threads窗口中有若干可用选项。它们在图10-42的上下文菜单中显示。注意Switch to Thread(切换到线程)选项。它允许你切换到正被调试的活动线程。该活动线程在线程列表(在标记的右侧)中用黄色箭头指示。切换活动线程将在调试窗口中改变调试上下文和内容。你也可以使用该上下文菜单来冻结(或者暂停)线程。这相当于挂起线程。

3. 基于特殊的线程中断

你也可以决定去中断基于调用线程的代码行。要这么做,设置一个断点并选择断点筛选器(前面讨论过)。图10-43给出了一个示例。你可以选择基于线程ID或者它的名称中断。在这种情况下,该断点将基于后一个选项来命中。当然,这要求你在代码中为线程命名。

 
图10-43 基于线程设置断点筛选器

 

 

抱歉!评论已关闭.