进程间通信msgsnd和msgrcv应用笔记

示例程序

接收端

//MsgrcvDemo.c 接收端
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/msg.h> 
#define MAX_TEXT 512
struct MSG_TEST {
    long int mFlag;
    char data[MAX_TEXT];
};
int main(){
    int index = 0;
    int msgid;
    struct MSG_TEST m_message;
    msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
    printf("%s : msgid=%d\n", __FILE__, msgid);
    if (msgid == -1) {
        fprintf(stderr, "msgget failed with error: %d\n", errno);
        exit(EXIT_FAILURE);
    }

    while(1) {
        if (msgrcv(msgid, (void *)&m_message, MAX_TEXT,0,0) == -1) {
                fprintf(stderr, "msgrcv failed with error: %d\n", errno);
                exit(EXIT_FAILURE);
        }
        printf("receiver : %s\n", m_message.data);
        if (strcmp(m_message.data, "message_04") == 0) {
            break;
        }
    }

    if (msgctl(msgid, IPC_RMID, 0) == -1) { // 删除消息队列
        fprintf(stderr, "msgctl(IPC_RMID) failed\n");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}

发送端

// MsgsndDemo.c 发送端
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/msg.h>
#define MAX_TEXT 512
struct MSG_TEST {
    long int mFlag;
    char data[MAX_TEXT];
};// 两方消息格式一致即可
int main(){
    struct MSG_TEST m_message;
    int msgid;
    char buffer[BUFSIZ];
    int index = 0;
    msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
    printf("%s : msgid=%d\n", __FILE__, msgid);
    if (msgid == -1) {
        fprintf(stderr, "msgget failed with error: %d\n", errno);
        exit(EXIT_FAILURE);
    }
    while(index < 5) {
        sprintf(m_message.data, "message_%02d", index++);
        sleep(1);
        printf("send : %s\n", m_message.data);
        if (msgsnd(msgid, (void *)&m_message, MAX_TEXT, 0) == -1) { 
            fprintf(stderr, "msgsnd failed\n");
            exit(EXIT_FAILURE);
        }
    }
    exit(EXIT_SUCCESS);
}

分别启动接收端和发送端两个应用程序。每隔1秒,接收端收到一次发送端的数据;

函数解析:

int msgget(key_t key, int msgflg);
从内核的消息队列中取出一个消息队列的实例。
获取方式 msgflg:
IPC_PRIVATE: 创建一个该进程独占的消息队列,其它进程不能访问该消息队列
IPC_CREAT: 若消息队列不存在,创建一个新的消息队列,若消息队列存在,返回存在的消息队列,系统范围内使用

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
向指定的消息队列中发送一条信息。
msgflg 表示是否阻塞(0表示阻塞方式,设置IPC_NOWAIT 表示非阻塞方式)

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
从指定的消息队列中取出一条信息。
msgtyp 决定从队列中返回哪条消息(0表示返回消息队列中第一条消息)
msgflg 表示是否阻塞(0表示阻塞方式,设置IPC_NOWAIT 表示非阻塞方式)

int msgctl(int msqid, int cmd, struct msqid_ds *buf);
执行一条相关的消息队列操作命令。
这里是移除消息队列(IPC_RMID)。

消息队列是独立于应用程序之外,一旦生成,由内核维护。

使用shell命令可以查看
ipcs -q
查看当前用户范围下的内核中存在的消息队列
如果没有使用msgctl(IPC_RMID)等相关函数去移除队列,则该队列一直存在于系统中;

部分常用命令
ipcs -a 是默认的输出信息 打印出当前系统中所有的进程间通信方式的信息
ipcs -m 打印出使用共享内存进行进程间通信的信息
ipcs -q 打印出使用消息队列进行进程间通信的信息
ipcs -s 打印出使用信号进行进程间通信的信息
ipcrm -M shmkey 移除用shmkey创建的共享内存段
ipcrm -m shmid 移除用shmid标识的共享内存段
ipcrm -Q msgkey 移除用msqkey创建的消息队列
ipcrm -q msqid 移除用msqid标识的消息队列
ipcrm -S semkey 移除用semkey创建的信号
ipcrm -s semid 移除用semid标识的信号

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值