Oracle® Developer Studio 12.5: スレッドアナライザユーザーズガイド

印刷ビューの終了

更新: 2016 年 6 月
 
 

デッドロックチュートリアルのソースファイルの入手

このチュートリアルで使用するソースファイルは、Oracle Developer Studio 開発者ポータルのダウンロードエリアからダウンロードできます。

サンプルファイルをダウンロードして展開したあと、OracleDeveloperStudio12.5-Samples/ThreadAnalyzer ディレクトリからサンプルを見つけることができます。サンプルは din_philo サブディレクトリにあります。din_philo ディレクトリには、手順に関する DEMO ファイルと Makefile ファイルが 1 つずつありますが、このチュートリアルではそれらの手順に従わず、Makefile も使用しません。代わりに、コマンドを個別に実行していきます。

このチュートリアルに従うには、OracleDeveloperStudio12.5-Samples/ThreadAnalyzer/din_philo ディレクトリから din_philo.c ファイルを別のディレクトリにコピーするか、個々にファイルを作成し、次のコードリストからコードをコピーしてください。

食事する哲学者の問題をシミュレートする din_philo.c サンプルプログラムは、POSIX スレッドを使用する C プログラムです。このプログラムでは、潜在的デッドロックと実デッドロックの両方が示されます。

din_philo.c のソースコードリスト

din_philo.c のソースコードは次に示すとおりです。

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