需要的头文件:
#include <sys/ipc.h>
#include <sys/msg.h>
和消息队列相关的函数:
1.key_t ftok(const char *pathname,int proj_id);
2.int msgget(key_t, key, int msgflg);
3.int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);
4.int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);
5.int msgctl(int msgid, int command, struct msgid_ds *buf);
ftok() 的作用是根据两个参数产生唯一的键值,并且相同的参数产生相同的键值。
msgget() 的第一个参数就是 ftok() 产生的键值。也可以是任意的一个数值。这个值的作用是作为这个消息队列在系统里面的唯一标识。
msgget()的第二个参数:
IPC_CREATE:如果内核中不存在键值与key相等的消息队列,则新建一个消除队列:如果存在这样的消息队列,返回该消息队列的描述符。
IPC_EXCL:和IPC_CREATE一起使用,如果对应键值的消息队列已经存在,则出错,返回-1。
注意:IPC_EXCL单独使用是没有任何意义的。
该函数如果调用成功返回一个消息队列的描述符,否则返回-1。
我们的经常用法是: msgget(key, 0666|IPC_CREATE);
这里解释一下这里的0666。0开头是8进制字面常量,即代表二进制000 110 110 110,也可以使用S_IRUSR这些宏进行或运算,如下:
S_IRUSR
Permits the process that owns the data structure to read it.
S_IWUSR
Permits the process that owns the data structure to modify it.
S_IRGRP
Permits the group associated with the data structure to read it.
S_IWGRP
Permits the group associated with the data structure to modify it.
S_IROTH
Permits others to read the data structure.
S_IWOTH
Permits others to modify the data structure.
int msgsnd(int msgid,struct msgbuf *msgp,size_t msgsz,int msgflg);
msgsnd各参数含义如下:
msgid:函数向msgid标识的消息队列发送一个消息。
msgp:msgp指向发送的消息。
msgsz:要发送的消息的大小,不包含消息类型占用的4个字节。
msgflg:操作标志位。可以设置为0或者IPC_NOWAIT。如果msgflg为0,则当消息队列已满的时候,msgsnd将会阻塞,直到消息可以写进消息队列;如果msgflg为IPC_NOWAIT,当消息队列已满的时候,msgsnd函数将不等待立即返回。
msgsnd函数成功返回0,失败返回-1。常见错误码有:EAGAIN,说明消息队列已满;EIDRM,说明消息队列已被删除;EACCESS,说明无权访问消息队列。
对第二个成员msgbuf的特别说明:是一个指向准备发送消息的指针,但是消息的数据结构却有一定的要求,指针msg_ptr所指向的消息结构一定要是以一个长整型成员变量开始的结构体,接收函数将用这个成员来确定消息的类型。所以消息结构要定义成这样:
[cpp] view plaincopyprint?
1. struct my_message{
2. long int message_type;
3. /* The data you wish to transfer*/
4. };
msg_sz是msg_ptr指向的消息的长度,注意是消息的长度,而不是整个结构体的长度,也就是说msg_sz是不包括长整型消息类型成员变量的长度。
结构体中的 message_type 的作用会在接收消息的时候体现出来。还需要注意一点的是,发送的时候这个message_type不能为0,否则发送失败。
int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);
1.msgid, msg_ptr, msg_st的作用也函数msgsnd函数的一样。
2.msgtype可以实现一种简单的接收优先级。如果msgtype为0,就获取队列中的第一个消息。如果它的值大于零,将获取具有相同消息类型的第一个信息。如果它小于零,就获取类型等于或小于msgtype的绝对值的第一个消息。
3.msgflg:操作标志位。msgflg可以为IPC_NOWAIT,IPC_EXCEPT,IPC_NOERROR3个常量。这些值的意义分别为:
IPC_NOWAIT,如果没有满足条件的消息,调用立即返回,此时错误代码为ENOMSG;
IPC_EXCEPT,与msgtyp配合使用,返回队列中第一个类型不为msgtyp的消息;
IPC_NOERROR,如果队列中满足条件的消息内容大于所请求的msgsz字节,则把该消息截断,截断部分将被丢弃。
int msgctl(int msqid,int cmd,struct msqid_ds *buf);
msgctl系统调用对msqid标识的消息队列执行cmd操作,系统定义了3种cmd操作:IPC_STAT,IPC_SET,IPC_RMID,它们的意义如下:
IPC_STAT:该命令用来获取消息队列对应的msqid_ds数据结构,并将其保存到buf指向的地址空间。 每个消息队列都维护一个结构体msqid_ds,此结构体保存着消息队列当前的状态信息。
IPC_SET:该命令用来设置消息队列的属性,要设置的属性存储在buf中,可设置的属性包括:msg_perm.uid,msg_perm.gid,msg_perm.mode以及msg_qbytes。
IPC_RMID:从内核中删除msqid标识的消息队列。
Linux内存共享:
内存共享有四个函数:
int shmget(key_t key, size_t size, int shmflg)
void *shmat(int shmid, const void *shmaddr, int shmflg)
int shmdt(const void *shmaddr)
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
这四个函数的 关系是: shmget() 从系统申请分配size大小的内存,并用shmflag设置权限,并返回shmid。 然后shmat把内存连接到进程。Shmctl负责对共享内存的控制。Shmdt把共享内存从进程中删除。
#include <sys/ipc.h>
#include <sys/msg.h>
和消息队列相关的函数:
1.key_t ftok(const char *pathname,int proj_id);
2.int msgget(key_t, key, int msgflg);
3.int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);
4.int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);
5.int msgctl(int msgid, int command, struct msgid_ds *buf);
ftok() 的作用是根据两个参数产生唯一的键值,并且相同的参数产生相同的键值。
msgget() 的第一个参数就是 ftok() 产生的键值。也可以是任意的一个数值。这个值的作用是作为这个消息队列在系统里面的唯一标识。
msgget()的第二个参数:
IPC_CREATE:如果内核中不存在键值与key相等的消息队列,则新建一个消除队列:如果存在这样的消息队列,返回该消息队列的描述符。
IPC_EXCL:和IPC_CREATE一起使用,如果对应键值的消息队列已经存在,则出错,返回-1。
注意:IPC_EXCL单独使用是没有任何意义的。
该函数如果调用成功返回一个消息队列的描述符,否则返回-1。
我们的经常用法是: msgget(key, 0666|IPC_CREATE);
这里解释一下这里的0666。0开头是8进制字面常量,即代表二进制000 110 110 110,也可以使用S_IRUSR这些宏进行或运算,如下:
S_IRUSR
Permits the process that owns the data structure to read it.
S_IWUSR
Permits the process that owns the data structure to modify it.
S_IRGRP
Permits the group associated with the data structure to read it.
S_IWGRP
Permits the group associated with the data structure to modify it.
S_IROTH
Permits others to read the data structure.
S_IWOTH
Permits others to modify the data structure.
int msgsnd(int msgid,struct msgbuf *msgp,size_t msgsz,int msgflg);
msgsnd各参数含义如下:
msgid:函数向msgid标识的消息队列发送一个消息。
msgp:msgp指向发送的消息。
msgsz:要发送的消息的大小,不包含消息类型占用的4个字节。
msgflg:操作标志位。可以设置为0或者IPC_NOWAIT。如果msgflg为0,则当消息队列已满的时候,msgsnd将会阻塞,直到消息可以写进消息队列;如果msgflg为IPC_NOWAIT,当消息队列已满的时候,msgsnd函数将不等待立即返回。
msgsnd函数成功返回0,失败返回-1。常见错误码有:EAGAIN,说明消息队列已满;EIDRM,说明消息队列已被删除;EACCESS,说明无权访问消息队列。
对第二个成员msgbuf的特别说明:是一个指向准备发送消息的指针,但是消息的数据结构却有一定的要求,指针msg_ptr所指向的消息结构一定要是以一个长整型成员变量开始的结构体,接收函数将用这个成员来确定消息的类型。所以消息结构要定义成这样:
[cpp] view plaincopyprint?
1. struct my_message{
2. long int message_type;
3. /* The data you wish to transfer*/
4. };
msg_sz是msg_ptr指向的消息的长度,注意是消息的长度,而不是整个结构体的长度,也就是说msg_sz是不包括长整型消息类型成员变量的长度。
结构体中的 message_type 的作用会在接收消息的时候体现出来。还需要注意一点的是,发送的时候这个message_type不能为0,否则发送失败。
int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);
1.msgid, msg_ptr, msg_st的作用也函数msgsnd函数的一样。
2.msgtype可以实现一种简单的接收优先级。如果msgtype为0,就获取队列中的第一个消息。如果它的值大于零,将获取具有相同消息类型的第一个信息。如果它小于零,就获取类型等于或小于msgtype的绝对值的第一个消息。
3.msgflg:操作标志位。msgflg可以为IPC_NOWAIT,IPC_EXCEPT,IPC_NOERROR3个常量。这些值的意义分别为:
IPC_NOWAIT,如果没有满足条件的消息,调用立即返回,此时错误代码为ENOMSG;
IPC_EXCEPT,与msgtyp配合使用,返回队列中第一个类型不为msgtyp的消息;
IPC_NOERROR,如果队列中满足条件的消息内容大于所请求的msgsz字节,则把该消息截断,截断部分将被丢弃。
int msgctl(int msqid,int cmd,struct msqid_ds *buf);
msgctl系统调用对msqid标识的消息队列执行cmd操作,系统定义了3种cmd操作:IPC_STAT,IPC_SET,IPC_RMID,它们的意义如下:
IPC_STAT:该命令用来获取消息队列对应的msqid_ds数据结构,并将其保存到buf指向的地址空间。 每个消息队列都维护一个结构体msqid_ds,此结构体保存着消息队列当前的状态信息。
IPC_SET:该命令用来设置消息队列的属性,要设置的属性存储在buf中,可设置的属性包括:msg_perm.uid,msg_perm.gid,msg_perm.mode以及msg_qbytes。
IPC_RMID:从内核中删除msqid标识的消息队列。
Linux内存共享:
内存共享有四个函数:
int shmget(key_t key, size_t size, int shmflg)
void *shmat(int shmid, const void *shmaddr, int shmflg)
int shmdt(const void *shmaddr)
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
这四个函数的 关系是: shmget() 从系统申请分配size大小的内存,并用shmflag设置权限,并返回shmid。 然后shmat把内存连接到进程。Shmctl负责对共享内存的控制。Shmdt把共享内存从进程中删除。