山东大学操作系统实验四

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

软件学院操作系统实验报告实验题目:实验四、进程同步实验学号:201100300124日期:2013年05月10日班级:5班姓名:韩俊晓Email:hanjunxiao188@gmail.com实验目的:加深对并发协作进程同步与互斥概念的理解,观察和体验并发进程同步与互斥操作的效果,分析与研究经典进程同步与互斥问题的实际解决方案。了解Linux系统中IPC进程同步工具的用法,练习并发协作进程的同步与互斥操作的编程与调试技术。实验要求:抽烟者问题。假设一个系统中有三个抽烟者进程,每个抽烟者不断地卷烟并抽烟。抽烟者卷起并抽掉一颗烟需要有三种材料:烟草、纸和胶水。一个抽烟者有烟草,一个有纸,另一个有胶水。系统中还有两个供应者进程,它们无限地供应所有三种材料,但每次仅轮流提供三种材料中的两种。得到缺失的两种材料的抽烟者在卷起并抽掉一颗烟后会发信号通知供应者,让它继续提供另外的两种材料。这一过程重复进行。请用以上介绍的IPC同步机制编程,实现该问题要求的功能。硬件环境:实验室计算机软件环境:Ubuntu08.4-Linux操作系统BASH_VERSION='3.2.33(1)-releasegccversion4.1.2gedit2.18.2OpenOffice2.3实验步骤:实验思路:(1)对于生产者进程可以创建一个子进程,这样父子进程就构成了两个生产者,同时产生随机数来控制往共享内存中写的内容;(2)对于消费者进程,创建两个子进程,与父进程一起就构成了三个消费者进程,然后从共享内存中读取数据即可。1.实验说明:在linux系统中可以利用进程间通信(interprocesscommunication)IPC中的3个对象:共享内存、信号灯数组、消息队列,来解决协作并发进程间的同步与互斥的问题。1)共享内存是OS内核为并发进程间交换数据而提供的一块内存区(段)。如果段的权限设置恰当,每个要访问该段内存的进程都可以把它映射到自己私有的地址空间中。如果一进程更新了段中数据,那么其他进程立即会看到这一更新。进程创建的段也可由另一进程读写。linux中可用命令ipcs-m观察共享内存情况。$ipcs-m------SharedMemorySegments--------keyshmidownerpermsbytesnattchstatus0x00000000327682student6003932162dest0x00000000360451student6001966082dest0x00000000393220student6001966082destkey共享内存关键值shmid共享内存标识owner共享内存所由者(本例为student)perm共享内存使用权限(本例为student可读可写)byte共享内存字节数nattch共享内存使用计数status共享内存状态上例说明系统当前已由student建立了一些共享内存,每个都有两个进程在共享。2)信号灯数组是OS内核控制并发进程间共享资源的一种进程同步与互斥机制。linux中可用命令ipcs-s观察信号灯数组的情况。$ipcs-s------SemaphoreArrays--------keysemidownerpermsnsems0000000163844apache60010x4d00f259294920beagleind60080x00000159425995student6441semid信号灯的标识号nsems信号灯的个数其他字段意义同以上共享内存所述。上例说明当前系统中已经建立多个信号灯。其中最后一个标号为425996是由student建立的,它的使用权限为644,信号灯数组中信号灯个数为1个。3)消息队列是OS内核控制并发进程间共享资源的另一种进程同步机制。linux中可用命令ipcs-q观察消息队列的情况。$ipcs-q------MessageQueues--------keymsqidownerpermsused-bytesmessages0x000001c80root64481msgmid消息队列的标识号used-bytes消息的字节长度messages消息队列中的消息条数其他字段意义与以上两种机制所述相同。上例说明当前系统中有一条建立消息队列,标号为0,为root所建立,使用权限为644,每条消息8个字节,现有一条消息。4)在权限允许的情况下您可以使用ipcrm命令删除系统当前存在的IPC对象中的任一个对象。ipcrm-m21482删除标号为21482的共享内存。ipcrm-s32673删除标号为32673的信号灯数组。ipcrm-q18465删除标号为18465的消息队列。5)在linux的proc文件系统中有3个虚拟文件动态记录了由以上ipcs命令显示的当前IPC对象的信息,它们分别是:/proc/sysvipc/shm共享内存/proc/sysvipc/sem信号量/proc/sysvipc/msg消息队列我们可以利用它们在程序执行时获取有关IPC对象的当前信息。6)IPC对象有关的系统调用函数原型都声明在以下的头文件中:#includesys/types.h#includesys/ipc.h创建一段共享内存系统调用语法:#includesys/shm.hintshmget(key_tkey,intsize,intflags);key共享内存的键值,可以为IPC_PRIVATE,也可以用整数指定一个size共享内存字节长度flags共享内存权限位。shmget调用成功后,如果key用新整数指定,且flags中设置了IPC_CREAT位,则返回一个新建立的共享内存段标识符。如果指定的key已存在则返回与key关联的标识符。不成功返回-1令一段共享内存附加到调用进程中的系统调用语法:#includesys/shm.hchar*shmat(intshmid,char*shmaddr,intflags)shmid由shmget创建的共享内存的标识符shmaddr总为0,表示用调用者指定的指针指向共享段flags共享内存权限位shmat调用成功后返回附加的共享内存首地址令一段共享内存从到调用进程中分离出去的系统调用语法:#includesys/shm.hintshmdt(char*shmadr);shmadr进程中指向附加共享内存的指针shmdt调用成功将递减附加计数,当计数为0,将删除共享内存。调用不成功返回-1。创建一个信号灯数组的系统调用有语法:#includesys/sem.hintsemget(key_tkey,intnsems,intflags);key信号灯数组的键值,可以为IPC_PRIVATE,也可以用整数指定一个nsems信号灯数组中信号灯的个数flags信号灯数组权限位。如果key用整数指定,应设置IPC_CREAT位。semget调用成功,如果key用新整数指定,且flags中设置了IPC_CREAT位,则返回一个新建立的信号等数组标识符。如果指定的整数key已存在则返回与key关联的标识符。不成功返回-1操作信号灯数组的系统调用语法:#includesys/sem.hintsemop(intsemid,structsembuf*semop,unsignednops);semid由semget创建的信号灯数组的标识符semop指向sembuf数据结构的指针nops信号灯数组元素的个数。semop调用成功返回0,不成功返回-1。控制信号灯数组的系统调用语法:#includesys/sem.hintsemctl(intsemid,intsemnum,intcmd,unionsemunarg);semid由semget创建的信号灯数组的标识符semnum该信号灯数组中的第几个信号灯cmd对信号灯发出的控制命令。例如:GETVAL返回当前信号灯状态SETVAL设置信号灯状态IPC_RMID删除标号为semid的信号灯arg保存信号灯状态的联合体,信号灯的值是其中一个基本成员unionsemun{intval;/*valueforSETVAL*/......};semctl执行不成功返回-1,否则返回指定的cmd的值。创建消息队列的系统调用语法:#includesys/msg.hintmsgget(key_tkey,intflags)key消息队列的键值,可以为IPC_PRIVATE,也可以用整数指定一个flags消息队列权限位。msgget调用成功,如果key用新整数指定,且flags中设置了IPC_CREAT位,则返回一个新建立的消息队列标识符。如果指定的整数key已存在则返回与key关联的标识符。成功返回-1。追加一条新消息到消息队列的系统调用语法:#includesys.msg.hintmsgsnd(intmsqid,structmsgbuf*msgp,size_tmsgsz,intmsgflg);msqid由消息队列的标识符msgp消息缓冲区指针。消息缓冲区结构为:structmsgbuf{longmtype;/*消息类型,必须大于0*/charmtext[1];/*消息数据,长度应于msgsz声明的一致*/}msgsz消息数据的长度msgflg为0表示阻塞方式,设置IPC_NOWAIT表示非阻塞方式msgsnd调用成功返回0,不成功返回-1。从到消息队列中读出一条新消息的系统调用语法:#includesys.msg.hintmsgrcv(intmsqid,structmsgbuf*msgp,size_tmsgsz,longmsgtype,intmsgflg);msqid由消息队列的标识符msgp消息缓冲区指针。消息缓冲区结构为:structmsgbuf{longmtype;/*消息类型,必须大于0*/charmtext[1];/*消息数据,长度应于msgsz声明的一致*/}msgsz消息数据的长度msgtype决定从队列中返回哪条消息:=0返回消息队列中第一条消息0返回消息队列中等于mtype类型的第一条消息。0返回mtype=type绝对值最小值的第一条消息。msgflg为0表示阻塞方式,设置IPC_NOWAIT表示非阻塞方式msgrcv调用成功返回0,不成功返回-1。删除消息队列的系统调用语法:#includesys/msg.hintmsgctl(intmsqid,intcmd,structmsqid_ds*buf);msqid由消息队列的标识符cmd控制命令。常用的有:IPC_RMID删除msgid标识的消息队列IPC_STAT为非破坏性读,从队列中读出一个msgid_ds结构填充缓冲bufIPC_SET改变队列的UID,GID,访问模式和最大字节数。msgctl调用成功返回0,不成功返回-1。3.调试过程:1)建立以下名为ipc.h的C语言头文件:#includestdio.h#includestdlib.h#includesys/types.h#includesys/ipc.h#includesys/shm.h#includesys/sem.h#includesys/msg.h#defineBUFSZ256intget_ipc_id(char*proc_file,key_tkey);char*set_shm(key_tshm_key,intshm_num,intshm_flag);intset_msq(key_tmsq_key,intmsq);intset_sem(key_tsem_key,intsem_val,intsem_flag);intP(intsem_id);intV(intsem_id);typedefunionsemuns{intval;}Sem_uns;typedefstructmsgbuf{longmtype;charmtext[1];}Msg_buf;key_tbuff_key;intbuff_num;char*buff

1 / 16
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功