|
楼主 |
发表于 2005-6-28 12:33:10
|
显示全部楼层
嘻嘻,做好了。谢谢nait
主要的部分
要解决的问题:
1、 Unix下信号量的使用;算法中,使用了一组信号量(6个),其中5个信号量是分别对应一个哲学家,这样做的目的是当所需的叉子被占用时,想进餐的哲学家可以阻塞,另外1个信号量用作互斥,做临界资源的保护;
2、 Unix下PV操作的实现;Unix下并没有直接给出PV操作的函数,必须通过调用提供的相关操作,完成我们所需要的PV操作;
3、 Unix下共享存储的实现;算法中,使用了一个数组记录每个哲学家的状态,每一个哲学家行为都将记录在里面,当哲学家的状态发生变化,都必须对数组进行修改,这意味着每个哲学家都必须能访问到这个数组;在模拟的算法中,进程就对应着哲学家,因此必须建立共享内存,存放状态数组,以便各个哲学家进程都能访问;程序中还有一个监控进程,它每隔一段时间就会显示出哲学家的状态,它也必须能够访问到这块共享内存;
以上是本程序主要解决的问题,以下对每个问题进行分析解决。
具体问题分析设计:
1、 Unix下信号量的使用:
int semget(key_t key,int nsems,int permflags);
Unix使用semget调用创建或者获得信号量集合,三个参数中,其中key是唯一标示该信号量集合的标号,以后要获得已经创建的信号量都是通过它;nsems是要创建的信号量的个数,如果个数大于1,那么这将是一个信号量集合,其索引号是用0至到nsems-1;permflags是一组标志,其作用主要是说明该信号量的访问权限;
算法中
#define SEM_KEY 1002
定义了要用到的信号量集的key;
还有两个必须用到的关于信号量的系统调用:
int semctl(int semid,int sem_num,int command,union semun ctl_arg);
Int semop(int semid,struct sembuf *op_array,size_t num_ops);
semctl是用于对信号量的控制,如信号量值的设置获取等;semop是对信号量的操作,在下面将看到我定义的PV操作将使用到semop函数;
2、 Unix下PV操作的实现:
int p(int semid,int sem_index)
{
struct sembuf sb;
sb.sem_num = sem_index;
sb.sem_op = -1;
sb.sem_flg = SEM_UNDO;
if(semop(semid,&sb,1)==-1)
{
printf("ID(%d)--P():failed!\n",getpid());
return(FALSE);
}
return(TRUE);
}
int v(int semid,int sem_index)
{
struct sembuf sb;
sb.sem_num = sem_index;
sb.sem_op = 1;
sb.sem_flg = SEM_UNDO;
if(semop(semid,&sb,1)==-1)
{
printf("ID(%d)--V():failed!\n",getpid());
return(FALSE);
}
return(TRUE);
}
以上是PV操作的函数定义,通过传递给p()或v()一个semid和sem_index,对需要的信号量集合中的指定信号量进行操作;
3、 Unix下共享存储的实现:
Unix提供shmet、shmat和shmdt等一系列的相关系统调用用作共享存储的实现;
通过shmget函数来创建共享内存:
int shmget(key_t ket,size_t size,int shmflg);
类似于信号量的情况,程序需要提供一个key值去唯一标示共享内存块,而它返回一个以后程序需用到的共享内存标识码。
程序中
#define SHM_KEY_STATE 1000
标识共享状态数组
在创建共享内存后必须使用shmat函数来连接到进程中的地址空间,因此每个进程中必须定义个指针,用于指示这块内存空间。
在使用完毕后必须调用shmdt函数来讲共享内存和进程脱离。 |
|