操作允许权 八进制数 操作允许权 八进制数 用户可读 0400 小组可写 0020 用户可写 0200 其他可读 0004 小组可读 0040 其他可写 0002 控制命令 值 IPC_CREAT (创建) 0001000 2、发送一条消息到指定的消息队列 发送一条消息到指定的消息队列系统调用:msgsnd() 命令格式 int msgsnd(int msgid, struct msgbuf* msgp, int size, int flag); 功能 发送一个消息给指定描述符的消息队列。将msgp所指向的msgbuf中的消息复制到消息数据结构并挂到指定消息队列尾,唤醒等待消息的进程 msgqid msgp 参数说明 size flag 执行msgget()返回的消息队列的描述符 指向用户存储区的一个消息缓冲msgbuf的指针,在msgbuf中包含消息类型和消息正文 由msgp指向的数据结构中字符数组的长度(消息长度) 规定当核心用尽内部空间时应执行的动作。 例如:若在flag中设置了IPC_NOWAIT,则当消息队列中的字节数超过最大值msgsnd立即返回,否则msgsnd睡眠。flag可置0。 头文件 #include #include 3、从消息队列接收消息 从消息队列接收消息的系统调用:msgrcv() 命令格式 int msgrcv( int msgid, struct msgbuf* msgp, int size, int type, int flag); 功能 从指定的消息队列接收一个消息。将消息复制到msgp所指的msgbuf中,从消息队列中删除此消息,若消息未到则调用进程阻塞,并将该进程插入等待消息队列尾。 msgid 消息队列描述符; msgp size 参数说明 type 用来存放要接收消息的用户msgbuf的地址; msgp中数据数组的大小; =0 表示接收队列的第一个消息; 用户要读取的消息类型 >0 表示接收类型type的第一个消息; <0 表示接收小于或等于|type|的最低类型的第一个消息 flag 头文件 规定若该队列无消息,操作系统核心应当做什么,可设置为0. #include #include 4、对消息队列的操作 对消息队列操作的系统调用:msgctl() 命令格式 int msgctl( int msgid, int cmd, struct msgid_ds *buf ); 功能 返回值 查询一个消息队列的状态;设置或修改它的状态;撤消一个消息队列 函数调用成功返回0;不成功返回-1. 10
参数说明 msgid 该消息队列的描述符; cmd 规定命令的类型 ? IPC_STAT查询消息队列状态,将与msgid相关联的消息队列首标读入buf; ? IPC_SET设置或修改消息队列状态,设置有效用户、组标识、操作允许权,及字节数; ? IPC_RMID撤消描述符为msgid的消息队列; 含有控制参数或查询结果的用户缓冲区的地址,可设置为0 buf 头文件 #include #include 注意:设置和撤消消息队列的进程需要有一定的权限,如超级用户、具有有效用户ID、符合msg_perm权限设置等。
四、共享内存通信的系统调用 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 #include 2、将共享内存附接到进程的虚拟地址空间 将共享内存附接到进程虚拟地址空间的系统调用:shmat() 命令格式 功能 语句格式 字符型共享内存 数值型共享内存 字符型共享内存 数值型共享内存 shmid shmaddr 参数说明 shmflag shmat(int shmid, char *shmaddr, int msgflg, ulong *raddr); shmat(int shmid, int *shmaddr, int msgflg, ulong *raddr); viraddr=(char*) shmat(shmid, shmaddr, shmflag); viraddr=(int*) shmat(shmid, shmaddr, shmflag); 逻辑上将内部标识符为shmid的共享存储区附接到进程的虚拟地址空间shmaddr 共享存储区的描述符,可以由shmget()的返回值得到。 用户提供的共享存储区附接的虚地址。若shmaddr为0,则由系统选择一个适当的地址来附接该存储区。 规定了对该存储区的操作权限,以及系统是否要对用户规定的地址执行舍去操作。如果shmflag中设置了SHM_RND,则表示操作系统在必要时舍去这个地址;如果设置SHM_RDONLY则表示只允许读,11
shmflag为0表示可读可写。 viraddr 返回值 头文件 附接的虚地址。若定义为char *viraddr,则该共享内存作为字符存储区使用;若定义为int *viraddr,则该共享内存作为整型存储区使用。 正确时返回共享存储区附接后的虚地址,错误时返回-1。 #include #include 3、将共享内存从进程的地址空间断开 将共享内存从进程地址空间断开的系统调用:shmdt() 命令格式 shmdt(viraddr); 功能 返回值 头文件 将一个共享存储区从指定进程的虚拟地址空间断开 正确时返回0,错误时返回-1。 #include #include 参数说明 viraddr 系统调用shmat()所返回的虚地址 4、对共享内存的操作 对共享内存操作的系统调用:shmget() 命令格式 功能 shmctl(int shmid, int cmd, struct shmid_ds *buf) 对与共享存储区关联的各种参数进行操作,从而对共享存储区进行控制,包括删除共享存储区 shmid 共享存储区的内部标识符,由shmget()调用返回 buf 用户级数据结构地址,其结构类型与系统定义的shmid_ds一致,可以用0 规定操作的类型。其规定如下: ? IPC_STAT:返回包含在指定的shmid相关数据结构中的状态信息,并把它放置在用户存储区中的*buf指针所指的数据结构中。执行此命令的进程必须有读取允许权。 ? IPC_SET:对于指定的shmid,为它设置有效用户和小组标识符和操作存取权。 ? IPC_RMID:删除指定的shmid以及与它相关的共享存储区的数据结构。 ? SHM_LOCK:在内存中锁定指定的共享存储区,必须是超级用户才可以进行此项操作。 参数说明 cmd 返回值 头文件 正确时返回0,错误时返回-1。 #include #include 与消息缓冲类似,对于共享内存的删除也要有权限,如超级用户进程等,所以上机实习时应该使用root登录。
12