Linux_父子进程通过消息队列通信

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

#define SIZE 1024

const long id = 1000;//这里规定类型为1000的消息

typedef struct msgqueue{
        long mytype;//消息类型
        char mytext[SIZE];//消息内容
}msgqueue;

int main(){
    key_t k = ftok(".",0x1234);//申请key,确保两个需要通信的进程使用同一个key值获取到的队列id
    if(k < 0){
        perror("ftok");
        return -1;
    }
    int msgid = msgget(k,IPC_CREAT|IPC_EXCL|0666);//使用key值获取id
    if(msgid < 0){
        perror("msgget");
        return -1;
    }
    pid_t pid = fork();
    if(pid < 0){
        perror("fork");
        return -1;
    }
    if(pid > 0){//父进程发消息
        msgqueue queue;
        queue.mytype = id;//发送的消息类型为1000
        char msg[SIZE];
        while(1){//循环输入,此时输入的每一条消息,消息类型都是1000
            printf("father says# ");
//            fflush(stdout);
            fgets(msg,sizeof(msg)+1,stdin);//从标准输入获取字符串,以回车换行结束
            strcpy(queue.mytext,msg);
            if(msgsnd(msgid,&queue,sizeof(msg),0) == -1){//将信息挂载到消息队列里
                perror("msgsnd");
                return -1;
            }
            if(strncmp(msg,"end",3) == 0){//只要输入end,认为结束通信
                break;
            }
            usleep(500000);
        }
        waitpid(pid,NULL,0);//等待子进程退出
    }else if(pid == 0){//子进程取消息,注意消息队列里只要有人拿了消息,那么拿走的消息就不在消息队列里了
        msgqueue queue;
        while(1){//循环拿消息
            if(msgrcv(msgid,&queue,sizeof(queue.mytext),id,0) == -1){//从消息队列里取消息,取一个少一个
                perror("msgrcv");
                return -1;
            }
            if(strncmp(queue.mytext,"end",3)==0){//end就退出
                printf("father will quit,i quit too\n");
                break;
            }
            printf("child recv:%s\n",queue.mytext);
        }
        exit(EXIT_SUCCESS);
    }
    if(msgctl(msgid,IPC_RMID,NULL)<0){//删除消息队列,因为消息队列创建后不会自己删除,必须人为删除或者重启
        perror("msgctl");
        return -1;
    }
    printf("\n done \n");//没什么含义,只是为了表示这次的传输是正常退出的
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40425540/article/details/80105517