JavaScript is required to for searching.
跳过导航链接
退出打印视图
Oracle Solaris Studio 12.3:线程分析器用户指南     Oracle Solaris Studio 12.3 Information Library (简体中文)
search filter icon
search icon

文档信息

前言

1.  什么是线程分析器?它有什么作用?

2.  数据争用教程

3.  死锁教程

3.1 关于死锁

3.2 获取死锁教程源文件

3.2.1 din_philo.c 的源代码内容

3.3 哲学家就餐方案

3.3.1 哲学家如何发生死锁

3.3.2 为 1 号哲学家引入一段休眠时间

3.4 如何使用线程分析器查找死锁

3.4.1 编译源代码

3.4.2 创建死锁检测实验

3.4.3 检查死锁检测实验

3.4.3.1 使用线程分析器查看死锁检测实验

3.4.3.2 使用 er_print 查看死锁检测实验

3.5 了解死锁实验结果

3.5.1 检查出现死锁的运行

3.5.2 检查存在潜在死锁但仍可完成的运行

3.6 修复死锁和了解误报

3.6.1 使用令牌控制哲学家

3.6.1.1 误报的报告

3.6.2 另一种令牌机制

A.  线程分析器可识别的 API

B.  有用提示

3.2 获取死锁教程源文件

您可以从 Oracle Solaris Studio 开发者门户的样例下载区域中下载本教程所用的源文件。

在下载并解压缩样例文件之后,您可以在 SolarisStudioSampleApplications/ThreadAnalyzer 目录中找到样例。这些样例位于 din_philo 子目录中。din_philo 目录包含了 MakefileDEMO 说明文件,但是本教程并不遵循这些说明,也不使用 Makefile。本教程将逐步指导您执行命令。

为跟随本教程学习,您可以将 din_philo.c 文件从 SolarisStudioSampleApplications/ThreadAnalyzer/din_philo 目录复制到其他目录,也可以创建自己的文件并从下面列出的代码内容中复制代码。

模拟哲学家就餐问题的 din_philo.c 样例程序是一个使用 POSIX 线程的 C 程序。该程序可以同时展示潜在死锁和实际死锁。

3.2.1 din_philo.c 的源代码内容

din_philo.c 的源代码如下所示:

  1  /*
  2   * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All Rights Reserved.
  3   * @(#)din_philo.c 1.4 (Oracle) 10/03/26
  4   */
  5
  6  #include <pthread.h>
  7  #include <stdio.h>
  8  #include <unistd.h>
  9  #include <stdlib.h>
 10  #include <errno.h>
 11  #include <assert.h>
 12
 13  #define PHILOS 5
 14  #define DELAY 5000
 15  #define FOOD 100
 16
 17  void *philosopher (void *id);
 18  void grab_chopstick (int,
 19                       int,
 20                       char *);
 21  void down_chopsticks (int,
 22                        int);
 23  int food_on_table ();
 24
 25  pthread_mutex_t chopstick[PHILOS];
 26  pthread_t philo[PHILOS];
 27  pthread_mutex_t food_lock;
 28  int sleep_seconds = 0;
 29
 30
 31  int
 32  main (int argn,
 33        char **argv)
 34  {
 35      int i;
 36
 37      if (argn == 2)
 38          sleep_seconds = atoi (argv[1]);
 39
 40      pthread_mutex_init (&food_lock, NULL);
 41      for (i = 0; i < PHILOS; i++)
 42          pthread_mutex_init (&chopstick[i], NULL);
 43      for (i = 0; i < PHILOS; i++)
 44          pthread_create (&philo[i], NULL, philosopher, (void *)i);
 45      for (i = 0; i < PHILOS; i++)
 46          pthread_join (philo[i], NULL);
 47      return 0;
 48  }
 49
 50  void *
 51  philosopher (void *num)
 52  {
 53      int id;
 54      int i, left_chopstick, right_chopstick, f;
 55
 56      id = (int)num;
 57      printf ("Philosopher %d is done thinking and now ready to eat.\n", id);
 58      right_chopstick = id;
 59      left_chopstick = id + 1;
 60
 61      /* Wrap around the chopsticks. */
 62      if (left_chopstick == PHILOS)
 63          left_chopstick = 0;
 64
 65      while (f = food_on_table ()) {
 66
 67          /* Thanks to philosophers #1 who would like to take a nap
 68           * before picking up the chopsticks, the other philosophers
 69           * may be able to eat their dishes and not deadlock.
 70           */
 71          if (id == 1)
 72              sleep (sleep_seconds);
 73
 74          grab_chopstick (id, right_chopstick, "right ");
 75          grab_chopstick (id, left_chopstick, "left");
 76
 77          printf ("Philosopher %d: eating.\n", id);
 78          usleep (DELAY * (FOOD - f + 1));
 79          down_chopsticks (left_chopstick, right_chopstick);
 80      }
 81
 82      printf ("Philosopher %d is done eating.\n", id);
 83      return (NULL);
 84  }
 85
 86  int
 87  food_on_table ()
 88  {
 89      static int food = FOOD;
 90      int myfood;
 91
 92      pthread_mutex_lock (&food_lock);
 93      if (food > 0) {
 94          food--;
 95      }
 96      myfood = food;
 97      pthread_mutex_unlock (&food_lock);
 98      return myfood;
 99  }
100
101  void
102  grab_chopstick (int phil,
103                  int c,
104                  char *hand)
105  {
106      pthread_mutex_lock (&chopstick[c]);
107      printf ("Philosopher %d: got %s chopstick %d\n", phil, hand, c);
108  }
109
110  void
111  down_chopsticks (int c1,
112                   int c2)
113  {
114      pthread_mutex_unlock (&chopstick[c1]);
115      pthread_mutex_unlock (&chopstick[c2]);
116  }