【0807作业】使用消息队列实现AB进程对话+使用共享内存实现A进程打印字符串,B进程逆置字符串,打印结果为【正序 逆序 正序 逆序】

作业一:使用消息队列实现AB进程对话

① 打开两个终端,要求实现AB进程对话

  1. A进程先发送一句话给B进程,B进程接收后打印
  2. B进程再回复一句话给A进程,A进程接收后打印
  3. 重复1.2步骤,当收到quit后,要结束AB进程

② 实现随时收发:用多进程 多线程。

1)A终端

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
/***************************A终端***************************/
struct msgbuf
{
    long mtype;      //消息类型,必须大于0
    char mtext[128]; //消息内容
};
int main(int argc, const char *argv[])
{
    //创建key值
    key_t key = ftok("/home/ubuntu",1);
    if(key < 0)
    {
        perror("mkfifo");
        return -1;
    }
    //创建消息队列
    int msqid = msgget(key, IPC_CREAT|0664) ;
    if(msqid< 0)
    {
        perror("mkfifo");
        return -1;
    }                                                                           

    struct msgbuf Abuf;
    ssize_t res=0;
    //创建子进程
    pid_t cpid=fork();
    if(cpid > 0)  //父进程(发送),A终端发送消息,B终端接收消息
    {
        while(1)
        {
            Abuf.mtype=1;
            scanf("%s",Abuf.mtext);
            if(msgsnd(msqid, &Abuf,sizeof(Abuf.mtype),0) < 0)
            {
                perror("msgsnd");
                return -1;
            }
            if(strcmp(Abuf.mtext,"quit")==0)
                break;
        }
    }
    else if(0 == cpid) //子进程(接收),B终端发送消息,A终端接收
    {
        while(1)
        {
            msgrcv(msqid,&Abuf,sizeof(Abuf.mtext),2,0);
            if(res < 0)
            {
                perror("msgrcv");
                return -1;
            }
            if(strcmp(Abuf.mtext,"quit")==0)
                break;
            printf("%s\n",Abuf.mtext);
        }
        kill(getppid(),2);
    }
    else
    {
        perror("fork");
        return -1;
    }
    return 0;
}

2)B终端

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
/***************************B终端***************************/
struct msgbuf
{
    long mtype;      //消息类型,必须大于0
    char mtext[128]; //消息内容
};
int main(int argc, const char *argv[])
{
    //创建key值
    key_t key = ftok("/home/ubuntu",1);
    if(key < 0)
    {
        perror("mkfifo");
        return -1;
    }
    //printf("key = %#x\n",key);
    //创建消息队列
    int msqid = msgget(key, IPC_CREAT|0664) ;
    if(msqid< 0)
    {
        perror("mkfifo");
        return -1;
    }

    struct msgbuf Bbuf;
    ssize_t res=0;
    pid_t cpid=fork();
    if(cpid > 0)   //父进程(接收),A终端发送消息,B终端接收消息
    {   
        while(1)
        {
            Bbuf.mtype=2;
            scanf("%s",Bbuf.mtext);
            if(msgsnd(msqid, &Bbuf,sizeof(Bbuf.mtype),0) < 0)
            {
                perror("msgsnd");
                return -1;
            }
            if(strcmp(Bbuf.mtext,"quit")==0)
                break;
        }

    }
    else if(0 == cpid)  //子进程(发送),B终端发送消息,A终端接收
    {   
        while(1)
        {
            msgrcv(msqid,&Bbuf,sizeof(Bbuf.mtext),1,0);
            if(res < 0)
            {
                perror("msgrcv");
                return -1;
            }
            if(strcmp(Bbuf.mtext,"quit")==0)
                break;
            printf("%s\n",Bbuf.mtext);
        }
        kill(getppid(),2);
    }
    else
    {
        perror("fork");
        return -1;
    }
    return 0;
}

3)结果

作业二:使用共享内存实现A进程打印字符串,B进程逆置字符串,打印结果为【正序 逆序 正序 逆序】

打开两个终端,要求实现:

  1. 在共享内存中存入字符串 “1234567”
  2. A进程循环打印字符串,B进程循环倒置字符串,要求结果不允许出现乱序
  • 提示:共享内存中存储 flag + string.

1)程序

#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
    //创建key值
    key_t key = ftok("./",10);
    if(key < 0)
    {
        perror("ftok");
        return -1;
    }
    printf("key = %#x\n",key);

    //创建共享内存,获得shmid号
    int shmid = shmget(key,32,IPC_CREAT|0664);
    if(shmid < 0)
    {
        perror("shmget");
        return -1;
    }
    printf("shmid = %d\n",shmid);

    //映射共享内存到用户空间
    void* addr= shmat(shmid,NULL,0);
    if((void*)-1 == addr)
    {
        perror("shmat");
        return -1;
    }
    printf("addp = %p",addr);

    *(int*)addr=0;
    //strcat((char*)addr+4,"1234567");
    char *ptr=(char*)addr+4;
    strcpy(ptr,"1234567");
    pid_t cpid = fork();
    if(cpid > 0)  //父进程:打印
    {
        while(1)
        {
            if(0 == *(int*)addr)
            {
                printf("%s\n",(char*)addr+4);
                *(int*)addr=1;
            }
        }
    }
    else if(0 == cpid)  //子进程:逆置
    {
        char t;
        while(1)
        {
            if(1 == *(int*)addr)
            {
                char *p=(char*)addr+4;
                char *q=(char*)addr+4+strlen(ptr)-1;
                while(p<q)
                {
                    t=*p;
                    *p=*q;
                    *q=t;
                    p++;
                    q--;
                }
                *(int*)addr=0;
            }
        }
    }
    else
    {                                                        
        perror("fork");
        return -1;
    }
    return 0;
}
                                                            

2)结果

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值