3)int msgsnd(int msqid, struct msgbuf *msgp, int msgsz, int msgflg);
向msgid代表的消息队列发送一个消息,即将发送的消息存储在msgp指向的msgbuf结构中,消息的大小由msgze指定。
对发送消息来说,有意义的msgflg标志为IPC_NOWAIT,指明在消息队列没有足够空间容纳要发送的消息时,msgsnd是否等待。造成msgsnd()等待的条件有两种:当前消息的大小与当前消息队列中的字节数之和超过了消息队列的总容量;
当前消息队列的消息数(单位"个")不小于消息队列的总容量(单位"字节数"),此时,虽然消息队列中的消息数目很多,但基本上都只有一个字节。
msgsnd()解除阻塞的条件有三个:不满足上述两个条件,即消息队列中有容纳该消息的空间;
msqid代表的消息队列被删除;
调用msgsnd()的进程被信号中断;
调用返回:成功返回0,否则返回-1。
4)int msgctl(int msqid, int cmd, struct msqid_ds *buf);
该系统调用对由msqid标识的消息队列执行cmd操作,共有三种cmd操作:IPC_STAT、IPC_SET 、IPC_RMID。IPC_STAT:该命令用来获取消息队列信息,返回的信息存贮在buf指向的msqid结构中;
IPC_SET:该命令用来设置消息队列的属性,要设置的属性存储在buf指向的msqid结构中;可设置属性包括:msg_perm.uid、msg_perm.gid、msg_perm.mode以及msg_qbytes,同时,也影响msg_ctime成员。
IPC_RMID:删除msqid标识的消息队列;
调用返回:成功返回0,否则返回-1。
----------------------------------------------------------------------------------------------------------------------
/*msgserver.c*/
#include #include #include #include #include #include #include
#define MSG_FILE "msgserver.c"
#define BUFFER 255
#define PERM S_IRUSR|S_IWUSR
/* 服务端创建的消息队列最后没有删除,我们要使用ipcrm命令来删除的 */
/* ipcrm -q */
struct msgtype {
long mtype;
char buffer[BUFFER+1];
};
int main()
{
struct msgtype msg;
key_t key;
int msgid;
if((key=ftok(MSG_FILE,'a'))==-1)
{
fprintf(stderr,"Creat Key Error:%s\n", strerror(errno));
exit(1);
}
if((msgid=msgget(key, PERM|IPC_CREAT|IPC_EXCL))==-1)
{
fprintf(stderr, "Creat Message Error:%s\n", strerror(errno));
exit(1);
}
printf("msqid = %d\n", msgid);
while(1)
{
msgrcv(msgid, &msg, sizeof(struct msgtype), 1, 0);
fprintf(stderr,"Server Receive:%s\n", msg.buffer);
msg.mtype = 2;
msgsnd(msgid, &msg, sizeof(struct msgtype), 0);
}
exit(0);
}
/* msgclient.c */
#include #include #include #include #include #include #include #include
#define MSG_FILE "msgserver.c"
#define BUFFER 255
#define PERM S_IRUSR|S_IWUSR
struct msgtype {
long mtype;
char buffer[BUFFER+1];
};
int main(int argc, char **argv)
{
struct msgtype msg;
key_t key;
int msgid;
if(argc != 2)
{
fprintf(stderr,"Usage:%s string\n", argv[0]);
exit(1);
}
if((key=ftok(MSG_FILE,'a'))==-1)
{
fprintf(stderr,"Creat Key Error:%s\n", strerror(errno));
exit(1);
}
if((msgid=msgget(key, PERM))==-1)
{
fprintf(stderr,"Creat Message Error:%s\n", strerror(errno));
exit(1);
}
msg.mtype = 1;
strncpy(msg.buffer, argv[1], BUFFER);
msgsnd(msgid, &msg, sizeof(struct msgtype), 0);
memset(&msg, '\0', sizeof(struct msgtype));
msgrcv(msgid, &msg, sizeof(struct msgtype), 2, 0);
fprintf(stderr, "Client receive:%s\n", msg.buffer);
exit(0);
}