相信自己,只有不想做的,没有做不到的。
分类: LINUX
2013-12-16 22:05:43
消息队列
特点:指定的类型读取/发送消息
A.消息结构体
typedef struct
{
//消息类型必须在第一个字段
long type;
//正文部分
/存放数据/
char mtext[1024];
/发送的PID/
int pid;
....
}MSG;
//正文大小
#define MSG_LEN (sizeof(MSG) - sizeof(long))
B.发送消息
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
msgsnd(消息队列ID,消息存放的地址,消息正文大小,发送方式(IPC_NOWAIT:消息队列满,发送消息不阻塞,立即返回
; 0 : 阻塞的方式));
例如:发送消息类型是100,内容"hello word"
typedef struct
{
long type;
char mtext[1024];
}MSG;
MSG msg;
msg.type = 100;
strcpy(msg.mtext, "hello word");
msgsnd(msgid,&msg,MSG_LEN,0);
C.接受消息
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
msgrcv(消息队列ID,消息存放的地址,正文大小,消息的类型,读取的方式);
msgtyp: 0(总是读取消息队列第一个消息), > 0 (每次读取第一个指定的消息类型)
msgflg:0(要求读的消息类型不存在,阻塞),IPC_NOWAIT(如果没有要读的消息,不阻塞立即返回)
MSG msg;
msgrcv(msgid,&msg,MSG_LEN,100,0);
printf("*******************\n");
printf("TYPE : %d.\n",msg.type);
printf("MTEXT: %s.\n",msg.mtext);
实例如下:
msg_a,.c代码如下
#include
#include
#include
#include
#include
#include
#include
#define MSG_TYPE_A 100
#define MSG_TYPE_B 200
typedef struct
{
long type;
char buf[1024];
}MSG;
#define MSG_LEN (sizeof(MSG) - sizeof(long))
int send_msg(int msg_id,int pid)
{
MSG msg;
while(1)
{
fgets(msg.buf,sizeof(msg.buf),stdin);
msg.buf[strlen(msg.buf) - 1] = '\0';
msg.type = MSG_TYPE_A;
if(msgsnd(msg_id,&msg,MSG_LEN,0) < 0)
{
perror("Fail to msgsnd");
exit(EXIT_FAILURE);
}
if(strncmp(msg.buf,"quit",4) == 0)
{
kill(pid,SIGUSR1);
wait(NULL);
break;
}
}
return 0;
}
int recv_msg(int msg_id)
{
MSG msg;
while(1)
{
if(msgrcv(msg_id,&msg,MSG_LEN,MSG_TYPE_B,0) < 0)
{
perror("Fail to msgsnd");
exit(EXIT_FAILURE);
}
printf("********************\n");
printf("TYPE : %ld.\n",msg.type);
printf("MTEXT: %s.\n",msg.buf);
printf("********************\n");
if(strncmp(msg.buf,"quit",4) == 0)
{
kill(getppid(),SIGUSR1);
break;
}
}
return 0;
}
int main(int argc, const char *argv[])
{
int msg_id;
key_t key;
pid_t pid;
if((key = ftok(argv[1],'k')) < 0)
{
perror("Fail to ftok");
exit(EXIT_FAILURE);
}
if((msg_id = msgget(key,IPC_CREAT | 0666)) < 0)
{
perror("Fail to msgget");
exit(EXIT_FAILURE);
}
if((pid = fork()) < 0)
{
perror("Fail to fork");
exit(EXIT_FAILURE);
}
if(pid == 0)
{
recv_msg(msg_id);
}
if(pid > 0)
{
send_msg(msg_id,pid);
//删除消息队列
if(msgctl(msg_id,IPC_RMID,NULL) < 0)
{
perror("Fail to msgctl");
exit(EXIT_FAILURE);
}
}
exit(EXIT_SUCCESS);
}
msg_b.c代码如下
#include
#include
#include
#include
#include
#include
#include
#define MSG_TYPE_A 200
#define MSG_TYPE_B 100
typedef struct
{
long type;
char buf[1024];
}MSG;
#define MSG_LEN (sizeof(MSG) - sizeof(long))
int send_msg(int msg_id,int pid)
{
MSG msg;
while(1)
{
fgets(msg.buf,sizeof(msg.buf),stdin);
msg.buf[strlen(msg.buf) - 1] = '\0';
msg.type = MSG_TYPE_A;
if(msgsnd(msg_id,&msg,MSG_LEN,0) < 0)
{
perror("Fail to msgsnd");
exit(EXIT_FAILURE);
}
if(strncmp(msg.buf,"quit",4) == 0)
{
kill(pid,SIGUSR1);
wait(NULL);
break;
}
}
return 0;
}
int recv_msg(int msg_id)
{
MSG msg;
while(1)
{
if(msgrcv(msg_id,&msg,MSG_LEN,MSG_TYPE_B,0) < 0)
{
perror("Fail to msgsnd");
exit(EXIT_FAILURE);
}
printf("********************\n");
printf("TYPE : %ld.\n",msg.type);
printf("MTEXT: %s.\n",msg.buf);
printf("********************\n");
if(strncmp(msg.buf,"quit",4) == 0)
{
kill(getppid(),SIGUSR1);
break;
}
}
return 0;
}
int main(int argc, const char *argv[])
{
int msg_id;
key_t key;
pid_t pid;
if((key = ftok(argv[1],'k')) < 0)
{
perror("Fail to ftok");
exit(EXIT_FAILURE);
}
if((msg_id = msgget(key,IPC_CREAT | 0666)) < 0)
{
perror("Fail to msgget");
exit(EXIT_FAILURE);
}
if((pid = fork()) < 0)
{
perror("Fail to fork");
exit(EXIT_FAILURE);
}
if(pid == 0)
{
recv_msg(msg_id);
}
if(pid > 0)
{
send_msg(msg_id,pid);
//删除消息队列
if(msgctl(msg_id,IPC_RMID,NULL) < 0)
{
perror("Fail to msgctl");
exit(EXIT_FAILURE);
}
}
exit(EXIT_SUCCESS);
}