您的位置:首页 > 运维架构 > Linux

Linux 下进程间通信机制(五) 消息队列Message Queues

2011-08-25 09:40 429 查看
消息队列函数定义如下:

#include <sys/msg.h>

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

int msgget(key_t key, int msgflg);

int msgrcv(int msqid, void *msg_ptr, size_t msg_sz, long int msgtype, int msgflg);

int msgsnd(int msqid, const void *msg_ptr, size_t msg_sz, int msgflg);

与信息号和共享内存一样,头文件sys/types.h与sys/ipc.h通常也是需要的。

demo1

#include<sys/types.h>
#include<sys/ipc.h>
#include<stdio.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<string.h>

#define BUFSZ 512
#define TYPE 100

struct msgbuf{
long mtype;
char mtext[BUFSZ];
};

int main()
{
int qid, len;
key_t key;
struct msgbuf msg;

/*根据不同的路径和关键字产生key*/
if((key = ftok(".", 'a')) == -1)
{
perror("ftok");
exit(-1);
}

/*创建消息队列*/
if((qid = msgget(key, IPC_CREAT|0666)) == -1)
{
perror("mesgget");
exit(-1);
}
printf("opened queue %d\n", qid);

puts("please input the message to queue:");
if((fgets((&msg)->mtext, BUFSZ, stdin)) == NULL)
{
puts("no message\n");
exit(-1);
}
msg.mtype = TYPE;
len = strlen(msg.mtext) + 1;

/*添加消息到消息队列*/
if(msgsnd(qid, &msg, len, 0) < 0)
{
perror("msgsnd");
exit(-1);
}

/*从消息队列读取消息*/
if(msgrcv(qid, &msg, BUFSZ, 0, 0) < 0)
{
perror("msgrcv");
exit(-1);
}

printf("message is :%s\n",msg.mtext);

/*从系统中删除消息队列*/
if(msgctl(qid, IPC_RMID, NULL) < 0)
{
perror("msgctl");
exit(-1);
}
return 0;
}


demo2

两个进程通过消息队列机制实现交替发送信息

//clientA
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <sys/msg.h>

#define N 64
#define TYPEA 100
#define TYPEB 200

typedef struct
{
long mtype; /* Message type. */
char mtext
; /* Message text. */
}MSGBUF;

#define LEN (sizeof(MSGBUF)-sizeof(long))

int main()
{
key_t key;
int msgid;
MSGBUF buf;
pid_t pid;

if ((key = ftok(".", 'a')) == -1)
{
perror("ftok");
exit(-1);
}

if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1)
{
perror("msgget");
exit(-1);
}

if ((pid = fork()) == -1)
{
perror("fork");
exit(-1);
}

if (pid == 0)//send
{
while (1)
{
if (fgets(buf.mtext, N, stdin) == NULL)
{
perror("fgets");
exit(-1);
}
buf.mtext[strlen(buf.mtext)-1] = '\0';
buf.mtype = TYPEB;

if (msgsnd(msgid, (void *)&buf, LEN, 0) == -1)
{
perror("msgsnd");
exit(-1);
}

if (strncmp(buf.mtext, "quit", 4) == 0)
{
if (msgctl(msgid, IPC_RMID, NULL) == -1)
{
perror("msgctl");
exit(-1);
}
kill(getppid(), SIGUSR1);
exit(0);
}
}
}
else//recv
{
while (1)
{
if (msgrcv(msgid, &buf, LEN, TYPEA, 0) == -1)
{
perror("msgrcfv");
exit(-1);
}

printf("%s\n", buf.mtext);
if (strncmp(buf.mtext, "quit", 4) == 0)
{
kill(pid, SIGUSR1);
exit(0);
}
}
}

exit(0);
}

//clientB
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <sys/msg.h>

#define N 64
#define TYPEA 100
#define TYPEB 200

typedef struct
{
long   mtype;       /* Message type. */
char   mtext
;    /* Message text. */
}MSGBUF;

#define LEN (sizeof(MSGBUF)-sizeof(long))

int main()
{
key_t key;
int msgid;
MSGBUF buf;
pid_t pid;

if ((key = ftok(".", 'a')) == -1)
{
perror("ftok");
exit(-1);
}

if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1)
{
perror("msgget");
exit(-1);
}

if ((pid = fork()) == -1)
{
perror("fork");
exit(-1);
}

if (pid == 0)//send
{
while (1)
{
if (fgets(buf.mtext, N, stdin) == NULL)
{
perror("fgets");
exit(-1);
}
buf.mtext[strlen(buf.mtext)-1] = '\0';
buf.mtype = TYPEA;

if (msgsnd(msgid, (void *)&buf, LEN, 0) == -1)
{
perror("msgsnd");
exit(-1);
}

if (strncmp(buf.mtext, "quit", 4) == 0)
{
if (msgctl(msgid, IPC_RMID, NULL) == -1)
{
perror("msgctl");
exit(-1);
}
kill(getppid(), SIGUSR1);
exit(0);
}
}
}
else//recv
{
while (1)
{
if (msgrcv(msgid, &buf, LEN, TYPEB, 0) == -1)
{
perror("msgrcfv");
exit(-1);
}

printf("%s\n", buf.mtext);
if (strncmp(buf.mtext, "quit", 4) == 0)
{
kill(pid, SIGUSR1);
exit(0);
}
}
}

exit(0);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux struct null kill input cmd