プロセス(スレッド)間同期反発古典問題(二)哲学者問題
4577 ワード
問題の説明:
哲学者の問題は、抽象的なデッドロックと資源の消耗の問題に使用されます.には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 );
}