跳过导航链接 | |
退出打印视图 | |
Oracle Solaris Studio 12.3:线程分析器用户指南 Oracle Solaris Studio 12.3 Information Library (简体中文) |
本节说明如何使用线程分析器检查哲学家就餐程序中的死锁。
下面列出了导致实际死锁的哲学家就餐程序的一次运行。
% cc -g -o din_philo din_philo.c % collect -r deadlock -o din_philo.1.er din_philo Creating experiment database din_philo.1.er ... Philosopher 1 is done thinking and now ready to eat. Philosopher 2 is done thinking and now ready to eat. Philosopher 3 is done thinking and now ready to eat. Philosopher 0 is done thinking and now ready to eat. Philosopher 1: got right chopstick 1 Philosopher 3: got right chopstick 3 Philosopher 0: got right chopstick 0 Philosopher 1: got left chopstick 2 Philosopher 3: got left chopstick 4 Philosopher 4 is done thinking and now ready to eat. Philosopher 1: eating. Philosopher 3: eating. Philosopher 3: got right chopstick 3 Philosopher 4: got right chopstick 4 Philosopher 2: got right chopstick 2 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 1: got right chopstick 1 Philosopher 4: got left chopstick 0 Philosopher 4: eating. Philosopher 0: got right chopstick 0 Philosopher 3: got left chopstick 4 Philosopher 3: eating. Philosopher 4: got right chopstick 4 Philosopher 2: got left chopstick 3 Philosopher 2: eating. Philosopher 3: got right chopstick 3 Philosopher 1: got left chopstick 2 Philosopher 1: eating. Philosopher 2: got right chopstick 2 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 1: got right chopstick 1 Philosopher 4: got left chopstick 0 Philosopher 4: eating. Philosopher 0: got right chopstick 0 Philosopher 3: got left chopstick 4 Philosopher 3: eating. ... Philosopher 4: got right chopstick 4 Philosopher 2: got left chopstick 3 Philosopher 2: eating. Philosopher 2: got right chopstick 2 Philosopher 3: got right chopstick 3 (hang) Execution terminated by pressing CTRL-C
键入以下命令以使用 er_print 实用程序检查实验:
% er_print din_philo.1.er (er_print) deadlocks
Deadlock #1, Potential deadlock Thread #2 Lock being held: 0x215a0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Lock being requested: 0x215b8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Thread #3 Lock being held: 0x215b8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Lock being requested: 0x215d0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Thread #4 Lock being held: 0x215d0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Lock being requested: 0x215e8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Thread #5 Lock being held: 0x215e8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Lock being requested: 0x21600, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Thread #6 Lock being held: 0x21600, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Lock being requested: 0x215a0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Deadlock #2, Actual deadlock Thread #2 Lock being held: 0x215a0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Lock being requested: 0x215b8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Thread #3 Lock being held: 0x215b8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Lock being requested: 0x215d0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Thread #4 Lock being held: 0x215d0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Lock being requested: 0x215e8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Thread #5 Lock being held: 0x215e8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Lock being requested: 0x21600, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Thread #6 Lock being held: 0x21600, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Lock being requested: 0x215a0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Deadlocks List Summary: Experiment: din_philo.1.er Total Deadlocks: 2 (er_print)
以下屏幕抓图显示了线程分析器中显示的死锁信息。
图 3-2 din_philo.c 中检测到的死锁
线程分析器报告了 din_philo.c 的两个死锁,一个是潜在死锁,另一个是实际死锁。通过进一步检查,可以发现两个死锁是相同的。
该死锁涉及的循环链如下:
|
选择循环链中的第一个线程(线程 2),然后单击 "Dual Source"(双源)标签,可以在源代码中看到,线程 2 获得了地址 0x215a0 处的锁,在源代码中还可以看到,该线程请求了地址 0x215b8 处的锁。
以下屏幕抓图显示了对应于线程 2 的 "Dual Source"(双源)标签。屏幕抓图的上半部分显示了线程 2 通过在第 106 行调用 pthread_mutex_lock() 获取了地址 0x215a0 处的锁。屏幕抓图的下半部分显示了同一线程通过在第 106 行调用 pthread_mutex_lock() 请求了地址 0x215b8 处的锁。在对 pthread_mutex_lock() 的两次调用中,分别使用了不同的锁作为参数。通常,锁获取和锁请求操作可能不在同一源代码行上。
在屏幕抓图中每个源代码行的左侧会显示缺省的度量:"Exclusive Deadlocks"(互斥死锁)度量。此度量显示了该源代码行上报告的(死锁涉及的)锁获取或锁请求操作的总次数。只有属于死锁循环链一部分的源代码行才具有此度量的值,并且该值大于零。
图 3-3 din_philo.c 中的潜在死锁
如果提供足够大的休眠参数,哲学家就餐程序就可避免实际死锁并正常终止。但是,正常终止并不意味着程序可以完全避免死锁。它仅仅表示在给定的一次运行中,持有和请求的锁未形成死锁链。如果在其他运行中出现了时间变化,则仍可能会发生实际死锁。下面列出了由于引入 40 秒休眠时间而正常终止的哲学家就餐程序的一次运行。但是,er_print 实用程序和线程分析器会报告潜在死锁。
% cc -g -o din_philo_pt din_philo.c % collect -r deadlock -o din_philo_pt.1.er din_philo_pt 40 Creating experiment database tha.2.er ... Philosopher 0 is done thinking and now ready to eat. Philosopher 2 is done thinking and now ready to eat. Philosopher 1 is done thinking and now ready to eat. Philosopher 3 is done thinking and now ready to eat. Philosopher 2: got right chopstick 2 Philosopher 3: got right chopstick 3 Philosopher 0: got right chopstick 0 Philosopher 4 is done thinking and now ready to eat. Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 3: got left chopstick 4 Philosopher 3: eating. Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 0: got right chopstick 0 Philosopher 2: got left chopstick 3 Philosopher 2: eating. ... Philosopher 4: got right chopstick 4 Philosopher 3: got right chopstick 3 Philosopher 2: got right chopstick 2 Philosopher 4: got left chopstick 0 Philosopher 4: eating. Philosopher 4 is done eating. Philosopher 3: got left chopstick 4 Philosopher 3: eating. Philosopher 0: got right chopstick 0 Philosopher 0: got left chopstick 1 Philosopher 0: eating. Philosopher 3 is done eating. Philosopher 2: got left chopstick 3 Philosopher 2: eating. Philosopher 0 is done eating. Philosopher 2 is done eating. Philosopher 1: got right chopstick 1 Philosopher 1: got left chopstick 2 Philosopher 1: eating. Philosopher 1 is done eating. % Execution terminated normally
键入下列以粗体显示的命令以使用 er_print 实用程序检查实验:
% er_print din_philo_pt.1.er (er_print) deadlocks Deadlock #1, Potential deadlock Thread #2 Lock being held: 0x215a0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Lock being requested: 0x215b8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Thread #3 Lock being held: 0x215b8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Lock being requested: 0x215d0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Thread #4 Lock being held: 0x215d0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Lock being requested: 0x215e8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Thread #5 Lock being held: 0x215e8, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Lock being requested: 0x21600, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Thread #6 Lock being held: 0x21600, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Lock being requested: 0x215a0, at: grab_chopstick + 0x0000002C, line 106 in "din_philo.c" Deadlocks List Summary: Experiment: din_philo_pt.1.er Total Deadlocks: 1 (er_print)
以下屏幕抓图显示了线程分析器界面中的潜在死锁信息。
图 3-4 din_philo.c 中的潜在死锁