进程间通信之消息队列的基本使用

/**********************************************
 * 进程间通信之消息队列
 * *******************************************/

#include<sys/types.h>
#include<sys/msg.h>
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<signal.h>
#include<sys/wait.h>


struct Msg
{
    long msg_type;
    char msg_text[1024];
};


void sigcb(int no)
{
    while(waitpid(-1, NULL, WNOHANG)>0);
}
int main()
{
    //signal(SIGCHLD, sigcb);
    pid_t pid;

    key_t key1;
    key1 = ftok("./file.txt", 1);
    if(key1 == -1)
    {
        printf("生成键值失败!!!\n");
    }

    //1.创建消息队列
    //msget();
    //int msgget(key_t key, int msgflg);
    //msgflg:标识与权限组合
    //       IPC_CREAT 存在则直接使用,否则创建新的消息队列
    //       0         获取存在的消息队列
    //成功 返回标识符 失败:-1

    //2.像消息队列写入数据
    //int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
    //msgqid 消息队列标识符
    //msgp   消息结构体指针
    //msgsz  消息内容长度
    //msgflg 可选标志
    //    0:         消息队列已满则阻塞
    //    IPC_NOWAIT:如果满了不阻塞直接返回
    //成功:0 失败:-1
    //printf("请输入要写入的数据:");
    //scanf("%s", msg.msg_text);

    pid = fork();
    int QueueFlag;
    //让父进程写入,子进程读取·
    if(pid > 0)
    {
        QueueFlag = msgget(key1, IPC_CREAT|0664);
        if(QueueFlag == -1)
        {
            printf("创建消息队列失败!!!\n");
            return 0;
        }
        printf("parent open msg success: %d\n", QueueFlag);
        struct Msg msg;
        int i;
        //strcpy(msg.msg_text, "nihao");
        printf("请输入要写入的数据:");
        scanf("%s", msg.msg_text);
        msg.msg_type = 2;
        i = msgsnd(QueueFlag, (struct Msg*)&msg, strlen(msg.msg_text),0);
        if(i == -1)
        {
            printf("写入数据失败\n");
            return 0;
        }
        wait(NULL);
    //删除队列
    //int msgctl(int msqid, int cmd, struct msqid_ds *buf);
    //msqid:消息队列标识符
    //cmd:  控制命令
    //  IPC_RMID: 删除消息队列
    //  IPC_STAT:获取msqid_ds结构,保存早buf中
    //  IPC_SET: 设置msqid_ds,按照buf指向的结构体的值
    //buf:  指针
    //成功 0 失败:-1
    
    int num;
    num = msgctl(QueueFlag, IPC_RMID, NULL);
    if(num == -1)
    {
        printf("删除消息队列失败\n");
        return 0;
    }
    printf("删除消息队列成功!\n");
    
    return 0;
    }
    else if(pid == 0)
    {
    //3.读取数据并移除
    //ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
    //msqid  消息队列标识符
    //msgp   消息队列结构体指针
    //msgsz  要读取的数据长度
    //msgtyp 读取的数据类型
    //msgflg 接收消息的可选标志
    //   0:         队列为空,阻塞
    //   IPC_NOWAIT:队列为空则立即返回-1
    //   MSG_NOERROR:若消息长度大于接受长度,截断返回,否则报错返回
    //   成功:接受字节数 失败:-1
        //int QueueFlag;
        QueueFlag = msgget(key1, IPC_CREAT|0664);
        if(QueueFlag == -1)
        {
            printf("创建消息队列失败!!!\n");
            return 0;
        }
        struct Msg msg;
        ssize_t size;
        size = msgrcv(QueueFlag, (struct Msg*)&msg, sizeof(msg.msg_text), 2, 0);
        printf("child open msg success: %d\n", QueueFlag);
        if(size == -1)
        {
            printf("读取数据失败\n");
            return 0;
        }
        printf("接受到[%d]个字节,数据:%s\n", size, msg.msg_text);
        
    }
else
    {
        printf("创建子进程失败\n");
        return 0;
    }
}

猜你喜欢

转载自blog.csdn.net/IT_xiaoQ/article/details/105507302