进程间的通信之消息队列

一、消息队列

消息队列就是一个消息列表,用户可以在消息队列中添加消息、读取消息,并且还可以通过消息类型来发送和接收消息,这样就有了选择,而不是被动接收消息,并且消息队列的发送和接收可以独立存在而不会出现单独运行一个读/写进程而失败,还提供了同步机制。

二、函数原型

1.创建/打开消息队列

int msgget(key_t key, int flag);

key:只要独一无二就行,所以可以手动指定,也可以用ftok函数来返回一个独一无二的值,因为这个值只是为了关联这个消息队列的。

flag:消息队列的访问权限,一般加上IPC_CREAT,这个会更好点,因为第一次通过这个key是创建,其他都是打开。

返回值:成功 消息队列ID  出错  -1

2.添加消息到队列

int msgsnd(int msgid, const void* msgp, size_t size, int flag);

msgid: 消息队列ID

msgp: 指向消息的指针, 必须是第一个成员为 long mtype(消息类型)的结构体

size:发送的消息正文的字节数

flag:用于控制当前消息队列满或队列消息到达系统范围的限制时将要发生的事情,0表示发送完成函数才返回,IPC_NOWAIT消息没发完也返回

返回值:成功 0 出错 -1

3.读取消息队列

int msgrcv(int msgid, void* msgp, size_t size, long msgtype, int flag);

msgid: 消息队列ID

msgp: 接收消息的缓冲区

size: 要接收的消息字节数

msgtype: 0:接收消息队列第一个消息 ;>0:接收消息队列第一个类型为msgtype的消息 ; 0< 接收消息队列中类型值不大于msgtype的绝对值且类型值又最小的消息

flag: 0:若没有消息函数会一直阻塞 IPC_NOWAIT: 若没有消息,进程会立即返回ENOMSG

返回值:成功 :接收到的消息的长度  失败:-1

4.控制消息队列

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

msgid: 消息队列ID

cmd: IPC_STAT:读取消息队列的属性,并将其保存在buf指向的缓冲区中 IPC_SET:设置消息队列的属性,这个值取自buf参数 IPC_RMID:从系统中删除消息队列

buf: 消息队列缓冲区

返回值: 成功: 0     出错: -1

三、应用实例

msg_write.c

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

#define BUF_SIZE 1024

int main(int argc, char* argv[])  
{  
    void* shmaddr;  
    char* buf;  
    int msg_id;  
    struct msgbuf
    {
    	long mtype;
    	char mtext[BUF_SIZE];
    };
    struct msgbuf msg_buf;
    msg_buf.mtype = 1;
    
    if (-1 == (msg_id = msgget((key_t)1468, 0666 | IPC_CREAT)))  
    {  
        perror("msgget failed!");  
        exit(1);  
    }  
      
    while(1)  
    {  
        printf("write buf: ");  
        fgets(msg_buf.mtext, BUF_SIZE, stdin);
        if (-1 == msgsnd(msg_id, (void*)&msg_buf, BUF_SIZE, 0))  
    	{  
        	perror("msgsend failed!");  
        	exit(1);  
    	}  
        if (strncmp(msg_buf.mtext, "bye", 3) == 0)  
        {  
            break;  
        }
        usleep(500);  
    }  
      
    if (msgctl(msg_id, IPC_RMID, NULL) < 0)  
    {  
        perror("msgctl failed!");  
        exit(1);  
    }  
                  
    return 0;  
} 
msg_read.c

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

#define BUF_SIZE 1024

int main(int argc, char* argv[])  
{  
    void* shmaddr;  
    char* buf;  
    int msg_id;  
    struct msgbuf
    {
    	long mtype;
    	char mtext[BUF_SIZE];
    };
    struct msgbuf msg_buf;
    
    if (-1 == (msg_id = msgget((key_t)1468, 0666 | IPC_CREAT)))  
    {  
        perror("msgget failed!");  
        exit(1);  
    }  
      
    while(1)  
    {  
        if (-1 == msgrcv(msg_id, (void*)&msg_buf, BUF_SIZE, 1, 0))  
    	{  
        	perror("msgsend failed!");  
        	exit(1);  
    	}  
    	printf("read buf: %s", msg_buf.mtext); 
        if (strncmp(msg_buf.mtext, "bye", 3) == 0)  
        {  
            break;  
        }  
    }  
                  
    return 0;  
}  



猜你喜欢

转载自blog.csdn.net/follow_blast/article/details/76137663