当前位置:首页 > 2009操作系统实验指导书Vmware版 - 图文
实验4进程通信
一、实验目的
1、加深理解进程通信的方法与原理;
2、掌握如何利用管道机制、消息缓冲队列、共享存储区机制进行进程间的通信。
二、实验内容 1、了解系统调用pipe()、msgget()、msgsnd()、msgrcv()、msgctl()、shmget()、shmat()、shmdt()、shmctl()的功能和实现过程。
2、编写一C语言程序,使其用管道来实现父子进程间通信。子进程向父进程发送字符串“is sending a message to parent!”;父进程则从管道中读出子进程发来的消息,并将其显示到屏幕上,然后终止。
3、运行该程序,观察、记录并简单分析其运行结果。
三、有名管道、无名管道系统调用 1、创建无名管道的系统调用 创建无名管道的系统调用:pipe() 格式 返回值 参数说明 功能 int pipe(int 管道名[2]); 0 1 正确返回 错误返回 管道名[1]:为写入端 管道名[2]:为读出端 创建一个管道名为指定名称的无名管道,以便于创建管道的进程及其子孙进程共享 头文件 include
? 当所有进程完成管道的操作后,管道的i结点和共享数据页被释放。
进程A的file结构i结点finodefop文件操作函数read、write等fp[1]父子进程write(fp[1],buf,size)finodefop文件操作函数read、write等fp[0]read(fp[0],buf,size)父子进程进程B的file结构数据页pipe(fp)图:管道的实现与父子进程的读写操作
2、读写管道的系统调用 读写管道的系统调用:write()、read() 格式 write(管道名[1], buf, size) 8
read(管道名[0], buf, size) 参数说明 说明 buf:程序中定义的字符型数组或缓冲区; size:读写的信息长度 管道为临界资源,父子进程之间除了需要读写同步以外,在对管道进行读写操作时还需要互斥进入。 为了保证管道操作过程中不至于因为用户的疏忽而死锁,Linux采用以下措施来避免死锁: ? 当进程因读或写等待时,要检查管道的另一端是否已经关闭,如果发现对方已经关闭则
直接返回,不再等待。
? 当进程关闭管道时,要检查管道的另一端是否正处于等待状态,如果是,则要先唤醒对
方,然后再关闭管道。
? 如果进程需要实现互斥,因为管道是文件,可以使用对文件上锁和开锁的系统调用。
3、文件上锁、开锁系统调用 文件上锁、开锁系统调用:lockf() 格式 lockf(files, function, size) files 参数说明 function size 是需要加以封锁的文件描述符,此处可以是管道的读写端口 为1表示上锁,为0表示开锁 表示锁定或开销的字节数,其值为0则表示文件全部内容
4、命名管道创建系统调用 命名管道创建系统调用:mkfifo() 格式 功能 返回值 头文件 int mkfifo(const char *pathname, mode_t mode); 专门用于创建FIFO 权限值,如0777表示所有用户都可读、可写、可执行 正确返回0,错误返回-1. #include
四、Linux消息缓冲通信的系统调用
1、创建一个消息队列或获取已存在消息队列的标识 创建消息队列/获取已存在消息队列的系统调用:msgget() 命令格式 int msgget(key_t key, int msgflag); 功能 返回值 创建标识为key值的消息队列或者获取已存在的消息队列的描述符msgid 正确返回该消息队列的描述符msgid; 错误返回-1。 msgqid 参数说明 key flag 头文件 9
语句格式 msgid=msgget (key, msgflag); 该系统调用返回的消息队列描述符,-1表示失败; 用户指定的消息队列标识符,为一正整数,其值可以由用户指定,如果使用IPC_PRIVATE则由系统产生key值; 用户设置的标志或访问方式,其值由操作权限和控制命令进行或运算得到 #include
参数说明 msgid 该消息队列的描述符; cmd 规定命令的类型 ? IPC_STAT查询消息队列状态,将与msgid相关联的消息队列首标读入buf; ? IPC_SET设置或修改消息队列状态,设置有效用户、组标识、操作允许权,及字节数; ? IPC_RMID撤消描述符为msgid的消息队列; 含有控制参数或查询结果的用户缓冲区的地址,可设置为0 buf 头文件 #include
四、共享内存通信的系统调用 1、创建或获取一个共享内存 创建/获取一个共享内存的系统调用:shmget() 命令格式 shmget(key, size, flag); 功能 说明 获得一个内部标识为shmid的共享存储区 该函数创建的共享内存区域并没有立即分配物理内存,而是创建一个文件对象shm_file来描述该区域。Shm_file文件并不属于磁盘文件,而是由内存页面组成,因此当系统亲面时,其中的内容也随之消失。 共享存储区关键字,可以由用户指定,如果使用IPC_PRIVATE,则其值由系统产生。 存储区的大小(字节数)。如果存储区定义为字符型,则大小为定义的字符个数;如果存储区定义为整型,大小可以使用sizeof(int)加以定义。 用户设置的标志或访问方式,与消息缓冲shmget中的含义相同。可以使用066|IPC_CREAT,表示任意进程可读可写。 语句格式 int shmid=int shmget(key_t key, int size, int flag); key 参数说明 size flag 返回值 头文件 正确时返回共享存储区的内部标识符shmid,错误时返回-1。 #include
shmflag为0表示可读可写。 viraddr 返回值 头文件 附接的虚地址。若定义为char *viraddr,则该共享内存作为字符存储区使用;若定义为int *viraddr,则该共享内存作为整型存储区使用。 正确时返回共享存储区附接后的虚地址,错误时返回-1。 #include
12
共分享92篇相关文档