8.29 消息队列、共享内存

作业:
1、将消息队列发送接收端实现一遍。

send.c:

#include<myhead.h>
struct msgbuf{
    long mtype;  //消息类型
    char mtext[1000];  //消息正文
};
#define TSIZE sizeof(struct msgbuf)-sizeof(long)
int main(int argc, char const *argv[])
{
    key_t key=ftok("./",65);
    if(key==-1)
    {
        perror("ftok");
        return -1;
    }
    printf("键:%#x\n",key);
    int msgID=msgget(key,IPC_CREAT|0664);
    if(msgID==-1)
    {
        perror("msgget");
        return -1;
    }
    printf("msgID:%d\n",msgID);

    struct msgbuf send;
    while(1)
    {
        printf("请输入消息类型:");
        scanf("%ld",&send.mtype);
        getchar();
        printf("请输入消息正文:");
        fgets(send.mtext,TSIZE,stdin);
        send.mtext[strlen(send.mtext)-1]='\0';
        msgsnd(msgID,&send,TSIZE,0);//阻塞发送,参数中size为正文大小而非整个结构体的大小
        if(strcmp(send.mtext,"quit")==0)
        {
            break;
        }
    }
    if(msgctl(msgID,IPC_RMID,NULL)==-1)
    {
        printf("删除队列失败!\n");
        return -1;
    }
    // struct msgbuf recv;
    // while(1)
    // {
    //     msgrcv(msgID,&recv,TSIZE,0,0);
    //     printf("%s\n",recv.mtext);
    // }
    return 0;
}

recv.c:

#include<myhead.h>
struct msgbuf{
    long mtype;  //消息类型
    char mtext[1000];  //消息正文
};
#define TSIZE sizeof(struct msgbuf)-sizeof(long)
int main(int argc, char const *argv[])
{
    key_t key=ftok("./",65);
    if(key==-1)
    {
        perror("ftok");
        return -1;
    }
    printf("键:%#x\n",key);
    int msgID=msgget(key,IPC_CREAT|0664);
    if(msgID==-1)
    {
        perror("msgget");
        return -1;
    }
    printf("msgID:%d\n",msgID);

    // struct msgbuf send;
    // while(1)
    // {
    //     printf("请输入消息类型:");
    //     scanf("%ld",&send.mtype);
    //     getchar();
    //     printf("请输入消息正文:");
    //     fgets(send.mtext,TSIZE,stdin);
    //     send.mtext[strlen(send.mtext)-1]='\0';
    //     msgsnd(msgID,&send,TSIZE,0);//阻塞发送,参数中size为正文大小而非整个结构体的大小
    //     if(strcmp(send.mtext,"quit")==0)
    //     {
    //         break;
    //     }
    // }
    struct msgbuf recv;
    while(1)
    {
        msgrcv(msgID,&recv,TSIZE,0,0);
        printf("%s\n",recv.mtext);
    }
    return 0;
}


2、将共享内存发送接收实现一遍.

send:

#include<myhead.h>
#include <sys/types.h>
#include <sys/shm.h>

#define PAGE_SIZE 4096

int main(int argc, char const *argv[])
{
    key_t key=ftok("./",'A');
    if(key==-1)
    {
        perror("ftok");
        return -1;
    }
    int shmID=shmget(key,PAGE_SIZE,IPC_CREAT|0664);
    if(shmID==-1)
    {
        perror("shmget");
        return -1;
    }
    char *shmADD=shmat(shmID,NULL,0);//映射内存地址
    if(shmADD==(void *)-1)
    {
        perror("shmat");
        return -1;
    }
    while(1)
    {
        printf("请输入共享内存的数据:");
        fgets(shmADD,sizeof(shmADD),stdin);
        if(strcmp(shmADD,"quit\n")==0)
        {
            break;
        }
    }

    if(shmdt(shmADD)==-1)//取消共享内存的映射
    {
        perror("shmdt");
        return -1;
    }
    return 0;
}

recv:

#include<myhead.h>
#include <sys/types.h>
#include <sys/shm.h>

#define PAGE_SIZE 4096

int main(int argc, char const *argv[])
{
    key_t key=ftok("./",'A');
    if(key==-1)
    {
        perror("ftok");
        return -1;
    }
    int shmID=shmget(key,PAGE_SIZE,IPC_CREAT|0664);
    if(shmID==-1)
    {
        perror("shmget");
        return -1;
    }
    char *shmADD=shmat(shmID,NULL,0);//映射内存地址
    if(shmADD==(void *)-1)
    {
        perror("shmat");
        return -1;
    }
    while(1)
    {
        
        fputs(shmADD,stdout);
        sleep(1);
        if(strcmp(shmADD,"quit\n")==0)
        {
            break;
        }
    }
    if(shmdt(shmADD)==-1)//取消共享内存的映射
    {
        perror("shmdt");
        return -1;
    }

    if(shmctl(shmID,IPC_RMID,NULL)==-1)//删除共享内存
    {
        perror("shmctl");
        return -1;
    }
    return 0;
}


建立两个.c建立子父进程,,父进程发送消息到队列,子进程读取队列,另一个同样。

usr1:

#include <myhead.h>

struct msgbuf
{
    long mtype;
    char mtext[1000];
};
#define TSIZE sizeof(struct msgbuf) - sizeof(long)
int main(int argc, char const *argv[])
{
    key_t key = ftok("./", 'B');
    if (key == -1)
    {
        perror("ftok");
        return -1;
    }
    pid_t pid = fork();
    if (pid > 0) //父进程
    {
        int msgid = msgget(key, IPC_CREAT | 0664);
        if (msgid == -1)
        {
            perror("msgget");
            return -1;
        }
        struct msgbuf message;
        while (1)
        {
            message.mtype = 1;
            fgets(message.mtext, sizeof(message.mtext), stdin);
            msgsnd(msgid, &message, TSIZE, 0);
            if (strcmp(message.mtext, "quit\n") == 0)
            {
                break;
            }
        }
        
        wait(NULL);
        if (msgctl(msgid, IPC_RMID, NULL) == -1)
        {
            perror("msgctl");
            return -1;
        }
        exit(EXIT_SUCCESS);
    }
    else if (pid == 0) //子进程
    {
        int msgid = msgget(key, IPC_CREAT | 0664);
        if (msgid == -1)
        {
            perror("msgget");
            return -1;
        }
        struct msgbuf message;
        while (1)
        {
            msgrcv(msgid, &message, TSIZE, 2, 0);
            fputs(message.mtext, stdout);
            if (strcmp(message.mtext, "quit\n") == 0)
            {
                break;
            }
        }
        exit(EXIT_SUCCESS);
    }else
    {
        perror("fork");
        return -1;
    }
    
    return 0;
}

usr2:

#include <myhead.h>

struct msgbuf
{
    long mtype;
    char mtext[1000];
};
#define TSIZE sizeof(struct msgbuf) - sizeof(long)
int main(int argc, char const *argv[])
{
    key_t key = ftok("./", 'B');
    if (key == -1)
    {
        perror("ftok");
        return -1;
    }
    pid_t pid = fork();
    if (pid > 0) //父进程
    {
        int msgid = msgget(key, IPC_CREAT | 0664);
        if (msgid == -1)
        {
            perror("msgget");
            return -1;
        }
        struct msgbuf message;
        while (1)
        {
            message.mtype = 2;
            fgets(message.mtext, sizeof(message.mtext), stdin);
            msgsnd(msgid, &message, TSIZE, 0);
            if (strcmp(message.mtext, "quit\n") == 0)
            {
                break;
            }
        }
        
        wait(NULL);
        if (msgctl(msgid, IPC_RMID, NULL) == -1)
        {
            perror("msgctl");
            return -1;
        }
        exit(EXIT_SUCCESS);
    }
    else if (pid == 0) //子进程
    {
        int msgid = msgget(key, IPC_CREAT | 0664);
        if (msgid == -1)
        {
            perror("msgget");
            return -1;
        }
        struct msgbuf message;
        while (1)
        {
            msgrcv(msgid, &message, TSIZE, 1, 0);
            fputs(message.mtext, stdout);
            if (strcmp(message.mtext, "quit\n") == 0)
            {
                break;
            }
        }
        exit(EXIT_SUCCESS);
    }else
    {
        perror("fork");
        return -1;
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值