资源预览内容
第1页 / 共4页
第2页 / 共4页
第3页 / 共4页
第4页 / 共4页
亲,该文档总共4页全部预览完了,如果喜欢就下载吧!
资源描述
实验五:用线程解决实验五:用线程解决“N“N 个哲学家个哲学家”问题问题姓名:姓名:邹受天邹受天学号:学号:22120051203895完成日期:完成日期:2008-1-2 姓名:姓名:叶剑媚叶剑媚学号:学号:22120051203933 完成日期:完成日期:2008-1-2一、实验内容一、实验内容1、目的、目的: 学习线程的编程和同步。2、要求、要求: 1)、程序语法philosopher_th -t N 是哲学家的个数(N = 2)。 time 是哲学家进餐和沉思的持续时间值,缺省为 2 秒。 2)、哲学家的编号为 0 N-1,分别用 N 个线程独立独立模拟。 3)、程序的输出要简洁,例如,当编号为 3 的哲学家在进餐时,就打印:philosopher 3 is eating 而当他在沉思时,则打印:philosopher 3 is thinking 不要输出其他任何信息。 4)、使用 pthread 的 semaphore.h 提供的信号量同步线程。二、具体设计二、具体设计1、设计与实现的主要原理、设计与实现的主要原理 在这个实验里,待解决的就是如何使用线程描述的问题。由于同一个进程中的所 有线程共享相同的内存空间,因此可以使用全局变量表示叉子。但是,为了避免“时间” 窗口,仍然必须使用“原子”操作进行互斥。可以使用在 semaphore.h 里说明的信号量 完成这个需求,具体细节参考课件和联机文档。如果哲学家中同时存在左撇子和右撇子, 则哲学家问题有解。因此在设计进程时应同时存在左撇子和右撇子,否则会出现哲学家 都“饿死”的现象。 命令格式为 philosopher_th -t ,N 是哲学家的个数(N = 2),是哲学家进餐和沉思的持续时间值,缺省值为 2 秒。功能是打印出每个哲学 家进餐和沉思的信息。为此可定义 N 个文件,分别表示 N 个叉子。每个哲学家先拿起一 边的叉子,若没拿到就一直等到拿到为止;若拿到了,则去试探另一手边是否有叉子, 若没有叉子则放下原有的叉子;若有,则同时拿到两个叉子进餐,这时可将代表这两个 的文件上锁,进餐规定的时间,然后放下叉子,即将这两个文件的状态释放。按照这样 的方式一直试探着拿叉子、放叉子,并不断打印出每个哲学家进餐和沉思的信息: thinking 或 eating,直到人为地终止它(如按 Ctrl-C 或 Ctrl-) 。2、设计构想:、设计构想: 为实现叉子功能可定义 5 个文件,分别表示 5 个叉子。其文件名可以按如下方式说明:static sem_t *forks; forks = (sem_t *) malloc( N * sizeof(sem_t) ); 哲学家的行为主要是 thinking(思考) ,takeFork(拿起叉子) ,eating(进餐) , putFork(放下叉子) 。thinking 和 eating 函数则较简单,只要打印相应信息并 sleep 规定 时间即可;在 takeFork 和 putFork 函数中考虑到要同时存在左撇子和右撇子,则可以令 第 5 个哲学家是左撇子,其余为右撇子,即第 5 个哲学家总是先拿左边的叉子再去拿右 边的叉子,先放左边的叉子再放右边的叉子,其余的相反。5 个哲学家的线程可以在主 程序中产生,在产生线程前要将各文件解锁,即保证开始状态时 5 把叉子都在桌上,而 每次有人进餐时都应将相应的文件上锁,结束后对文件进行释放,以便其他线程可以进 行操作。3、实验的具体设计如下:、实验的具体设计如下:#include “apue.h“ #include #include static sem_t *forks; static int nsecs,N;/拿起叉子可以如此定义: void takeFork(int i) if( i = N - 1 ) sem_wait( sem_wait( else sem_wait( sem_wait( /放下叉子可以如此定义: void putFork(int i) if( i = N - 1 ) sem_post( sem_post( else sem_post( sem_post( void thinking(int i,int nsecs) printf(“philosopher %d is thinking n“,i);sleep(nsecs); void eating(int i,int nsecs) printf(“philosopher %d is eating n“,i);sleep(nsecs); void* philosopher(void *n) inti = (int) n; while(1) thinking(i, nsecs); / 哲学家 i 思考 nsecs 秒 takeFork(i);/ 哲学家 i 拿起叉子 eating(i, nsecs);/ 哲学家 i 进餐 nsecs 秒 putFork(i);/ 哲学家 i 放下叉子 int main(int argc,char * argv) if(argc = 4)nsecs = atoi(argv3);else nsecs = 2;int i,status;N = atoi(argv1);forks = (sem_t *) malloc( N * sizeof(sem_t) );/ 分配 N 个信号量for( i = 0; i N; i+) sem_init(forks + i, 0, 1); / 初始化信号量pthread_t tpid;for(i = 0; i N; i+) status = pthread_create(if( tpid 0 )err_quit(“cant creat thread:%sn“,streeror(status); pthread_join(tpid, NULL);/* 注意,如果父进程不等待子进程的结束,那么需要终止 程序运行时,就只能从控制台删除在后台运行的哲学家进程 */return 0; 三、实验结果三、实验结果1、源程序名:philosopher_th.c 2、可执行程序名:philosopher_th 3、程序执行过程:(1)编译: gcc philosopher_th.c error2e.c -ophilosopher_th l pthread(2)运行过程: 操作 1:./ philosopher_th 5 运行结果如下图所示:操作 2:./ philosopher_th 5 t 3运行结果如下图所示:
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号