プロセス(スレッド)間同期反発古典問題(二)哲学者問題


問題の説明:
哲学者の問題は、抽象的なデッドロックと資源の消耗の問題に使用されます.
  • にはn個のフォークがあり、n個の哲学者は、哲学者ごとに2本のフォークが必要で、食事をすることができます.
  • 彼らは円卓を囲んで座っています.つまり、左手の右手にフォークがありますが、同じフォークかもしれません.
  • フォークごとに
  • しか使えません
    問題の分析:
    主にデッドロックとリソース消費の問題を考慮します.
  • デッドロックの状況を考慮して、誰もがフォークを持って、それではもう一人の哲学者がフォークを置くのを待っていて、それではすべてのプロセスは寝ていて、プロセスが目を覚ますことができなくて、それではデッドロック
  • に陥ります
  • 資源の枯渇を考慮して、フォークを持った哲学者が自分で目を覚ましてフォークを置いて、しばらくしてから再び手を取ると仮定すると、すべてのプロセスが同時に実行され始め、デッドロックと同じようにデッドロックに陥ることになります.

  • 基本的な考え方:
  • fork[MAX]は各フォークの状態を表し、各フォークには2つの状態がある.
  • 汚れ:初期値は、フォークが使用されていないか、現在の所有者が
  • を使用していることを示しています.
  • 浄:すでに取り上げられているが、
  • はまだ使われていないことを示している.
  • 空腹の科学者にとって、彼はまず両側のスプーンがきれいかどうかを尋ねます.
  • 汚れている場合は、現在の所有者に使用されているので、置くことができます.それでは、私は持って行って、フォークをきれいに拭くことができます.
  • きれいなフォークに対して、きっと使われるのを待っているに違いないので、私は寝て使い終わったら汚れたフォークを持っていくしかありません.
  • 二人の哲学者が同じ資源を競争する場合、番号の小さい哲学者
  • に譲る.
  • では、プログラミングを容易にするために、上記の概念を信号量に対応することを考えています.フォークごとに哲学者が操作するしかないので、混乱が起こらないことを保証することができます.フォークごとにロックが必要です.哲学者は汚いときにしか取ることができません.だから、フォークごとに初期値が1の信号量として使用すればいいです.そして、デッドロックの発生を防止するために、反発ロックを追加します.

  • コードは次のとおりです.
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define MAX 5
    #define TRUE 1
    
    #define p(x) sem_wait(&x)
    #define v(x) sem_post(&x)
    
    /*
    sem_wait(&x)
    sem_wait       ,             "1",
                            
    sem_post(&x)
            ,          "1"
    */
    
    sem_t forks[MAX];//       ,0    ,1   
    pthread_mutex_t mutex;
    
    void init ( )
    {
        int i;
        //      ,         (1)
        for ( i = 0 ; i < MAX ; i++ )
            sem_init( &forks[i] , 0 , 1 );
    }
    
    //           
    void * philosopher ( void* arg )
    {
        int* p = (int*)arg;
        int x = *p;//      id
        while ( TRUE )
        {
            pthread_mutex_lock(&mutex);
            p(forks[x]);//     ,               
            p(forks[(x+1)%MAX]);//  
            printf ( "the %dth philosopher having meal...
    "
    , x ); sleep(1);// ... v(forks[x]);// v(forks[(x+1)%MAX]);// pthread_mutex_unlock(&mutex); sleep(2);// } } int main ( ) { init ();// pthread_t id[MAX];// id int tid[MAX];// id int i; for ( i = 0 ; i < MAX ; i++ ) { tid[i] = i; // pthread_create ( &id[i] , NULL , philosopher , &tid[i] ); } // , for ( i = 0 ; i < MAX ; i++ ) pthread_join ( id[i] , NULL ); }