可以使用线程分析器检查程序中的潜在死锁和实际死锁。线程分析器沿用与 Oracle Solaris Studio 性能分析器相同的“收集-分析”模型。
使用线程分析器的过程涉及三个步骤:
编译源代码。
创建死锁检测实验。
检查实验结果。
编译代码并务必指定 -g。不要指定高优化级别,因为在高优化级别时报告的信息(如行号和调用栈)可能是错误的。应使用 -g -xopenmp=noopt 编译 OpenMP 程序,并仅使用 -g -mt 编译 POSIX 线程程序。
有关这些选项的更多信息,请参见 cc(1)、CC(1) 或 f95(1) 手册页。
对于本教程,请使用以下命令编译代码:
% cc -g -o din_philo din_philo.c |
使用线程分析器的带有 -r deadlock 选项的 collect 命令。此选项将在程序的执行期间创建死锁检测实验。
对于本教程,请使用以下命令创建名为 din_philo.1.er 的死锁检测实验:
% collect -r deadlock -o din_philo.1.er din_philo |
可以通过创建多个死锁检测实验来提高检测到死锁的可能性。对于各个实验,应使用不同的线程数和不同的输入数据。例如,在 din_philo.c 代码中,可以更改以下行中的值:
13 #define PHILOS 5 14 #define DELAY 5000 15 #define FOOD 100
然后可以像以前一样进行编译,并收集其他实验。
有关更多信息,请参见 collect(1) 和 collector(1) 手册页。
可以使用线程分析器、性能分析器或 er_print 实用程序检查死锁检测实验。线程分析器和性能分析器都提供 GUI 界面;线程分析器显示的是一组简化的缺省标签,但在其他方面与性能分析器完全相同。
要启动线程分析器并打开 din_philo.1.er 实验,请键入以下命令:
% tha din_philo.1.er |
线程分析器包含菜单栏、工具栏以及包含多个标签的拆分窗格(不同标签对应不同的显示)。
打开收集的死锁检测实验时,缺省情况下会在左侧窗格中显示以下标签:
"Deadlocks"(死锁)标签
此标签显示线程分析器在程序中检测到的潜在死锁和实际死锁列表。缺省情况下会选中此标签。其中会显示每个死锁涉及到的线程。这些线程形成一个循环链,其中每个线程都持有一个锁并请求该链中的下一个线程持有的另一个锁。
"Dual Source"(双源)标签
在 "Deadlocks"(死锁)标签上的循环链中选择一个线程,然后单击 "Dual Source"(双源)标签。"Dual Source"(双源)标签会显示该线程持有锁的源代码位置,以及同一线程请求锁的源代码位置。该线程持有锁和请求锁的源代码行会突出显示。
"Experiments"(实验)标签
此标签显示实验中的装入对象并列出所有错误和警告消息。
线程分析器显示屏的右侧窗格中会显示以下标签:
"Summary"(摘要)标签,显示从 "Deadlocks"(死锁)标签中选择的死锁的摘要信息。
"Deadlocks Details"(死锁详细信息)标签,显示从 "Deadlocks"(死锁)标签中选择的线程上下文的详细信息。
er_print 实用程序提供命令行界面。可以在交互式会话中使用 er_print 实用程序并在该会话期间指定子命令。也可以使用命令行选项以非交互方式指定子命令。
使用 er_print 实用程序检查死锁时,以下子命令非常有用:
-deadlocks
该选项会报告实验中检测到的所有潜在死锁和实际死锁。在 (er_print) 提示符下指定 deadlocks,或者在 er_print 命令行上指定 -deadlocks。
-ddetail deadlock_id
该选项会返回具有指定 deadlock_id 的死锁的详细信息。在 (er_print) 提示符下指定 -ddetail,或者在 er_print 命令行上指定 ddetail。如果指定的 deadlock_id 为 all,将显示所有死锁的详细信息。否则,请指定单个死锁编号,例如为第一个死锁指定 1。
-header
该选项会显示有关实验的描述性信息并报告所有错误或警告。在 (er_print) 提示符下指定 header,或者在命令行上指定 -header。
有关更多信息,请参阅 collect(1)、tha(1)、analyzer(1) 和 er_print(1) 手册页。