首页 > 其他分享 >消息队列练习题

消息队列练习题

时间:2024-05-28 08:59:55浏览次数:15  
标签:练习题 队列 errno pid fifo fd 消息 printf include

消息队列练习题

image

进程A

/********************************************************************
*          
*          file name:   mesqa.c
*          author:      [email protected]
*          date:        2024/5/28
*          function:    接收进程b的信号,读出消息队列中的信息
*          note:        应该先执行mesqb.c再执行该程序
*   
*        CopyRight (c)     2024/5/28   [email protected]      All Right Reseverd     
*          
********************************************************************/




#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#include <stdlib.h>




//管道标识符
int fifo_fd = 0;

//存储信息结构体
struct msgbuf 
{
    long mtype;      
    char mtext[128];    
};


/*****************************************************************************
*                 函数名称:     readmsg
*                 函数功能:    信号接收函数
*                 函数参数:    none
*                 返回结果:    none
*                 注意事项:    none
*                 函数作者:    [email protected]
*                 创建日期:    2024/5/28
*                 修改历史:    2024/5
*                 函数版本:    1.0
*
*****************************************************************************/
void readmsg()
{
    printf("信息接收,正在处理\n");
    struct msgbuf buf;
    //创建消息队列
    key_t key = ftok(".",22);
    int msg_id =msgget(key,IPC_CREAT|0664);
    if(-1 == msg_id){
        fprintf(stderr,"msg_id获取失败,errno[%d]:%s\n",errno,strerror(errno));
        exit(-1);
    }
    //读出信息
    int i = msgrcv(msg_id,&buf,sizeof(buf),0,0);
    if(-1 == i){
        fprintf(stderr,"msgrcv获取失败,errno[%d]:%s\n",errno,strerror(errno));
        exit(-1);
    }
    printf("i = %d\n",i);
    printf("%s\n",buf.mtext);
    printf("信息处理完毕\n");
}



int main()
{   //获取当前进程的pid
    int b_pid = 0;
    int a_pid = getpid();
    //打开管道文件
    fifo_fd = open("./fifopid",O_RDWR);
    if(-1 == fifo_fd){
        fprintf(stderr,"管道文件打开失败 errno[%d]:%s\n",errno,strerror(errno));
        return -1;
    }
    //读管道
    read(fifo_fd,&b_pid,sizeof(b_pid));
    printf("b_pid = %d\n",b_pid);
    close(fifo_fd);

    //重新打开管道
    fifo_fd = open("./fifopid",O_RDWR);
    if(-1 == fifo_fd){
        fprintf(stderr,"管道文件打开失败 errno[%d]:%s\n",errno,strerror(errno));
        return -1;
    }
    //写入管道
    write(fifo_fd,&a_pid,sizeof(a_pid));
    printf("a_pid = %d\n",a_pid);

    //发送信号
    kill(b_pid,SIGUSR1);
    printf("信息发送完毕\n");
    //接收信号
    signal(SIGUSR2,readmsg);
  

    while(1);
    close(fifo_fd);
    return 0;
}

进程B

/********************************************************************
*          
*          file name:   mesqb.c
*          author:      [email protected]
*          date:        2024/5/28
*          function:    接收进程a的信号,向消息队列写入信息
*          note:        应该先执行mesqb.c再执行该程序
*   
*        CopyRight (c)     2024/5/28   [email protected]      All Right Reseverd     
*          
********************************************************************/


#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#include <stdlib.h>


//pid标识符
int a_pid = 0;
int b_pid = 0;

//管道标识符
int fifo_fd = 0;

struct msgbuf 
{
    long mtype;      
    char mtext[128];    
};



/*****************************************************************************
*                 函数名称:     wrimsg
*                 函数功能:    信号接收函数
*                 函数参数:    none
*                 返回结果:    none
*                 注意事项:    none
*                 函数作者:    [email protected]
*                 创建日期:    2024/5/28
*                 修改历史:    2024/5
*                 函数版本:    1.0
*
*****************************************************************************/
void wrimsg()
{   
    printf("信息接收,正在处理\n");
    struct msgbuf buf;
    sprintf(buf.mtext,"BPID is %d\n",b_pid);
    printf("%s\n",buf.mtext);
    //打开管道文件
    fifo_fd = open("./fifopid",O_RDWR);
    if(-1 == fifo_fd){
        fprintf(stderr,"管道文件打开失败 errno[%d]:%s\n",errno,strerror(errno));
        exit(-1);
    }

    //读管道
    read(fifo_fd,&a_pid,sizeof(a_pid));
    printf("a_pid = %d\n",a_pid);
    //创建消息队列
    key_t key = ftok(".",22);
    int msg_id =msgget(key,IPC_CREAT|0664);
    if(-1 == msg_id){
        fprintf(stderr,"msg_id获取失败,errno[%d]:%s\n",errno,strerror(errno));
        exit(-1);
    }
    //写入信息
    msgsnd(msg_id,&buf,strlen(buf.mtext),0);
    //发送信号
    kill(a_pid,SIGUSR2);
    printf("信息发送完毕\n");
    close(fifo_fd);
}



int main()
{  
    b_pid = getpid();
    printf("b_pid = %d\n",b_pid);

    //创建管道文件
    int fifo = mkfifo("./fifopid",0644);
    if(-1 == fifo){
        fprintf(stderr,"管道文件创建失败 errno[%d]:%s\n",errno,strerror(errno));
        return -1;
    }
    //打开管道文件
    fifo_fd = open("./fifopid",O_RDWR);
    if(-1 == fifo_fd){
        fprintf(stderr,"管道文件打开失败 errno[%d]:%s\n",errno,strerror(errno));
        return -1;
    }

    //写入管道文件
    write(fifo_fd,&b_pid,sizeof(b_pid));
    printf("b_pid = %d\n",b_pid);
   
    //接收信号
    signal(SIGUSR1,wrimsg);

    while(1);
    close(fifo_fd);

    return 0;
}

标签:练习题,队列,errno,pid,fifo,fd,消息,printf,include
From: https://www.cnblogs.com/waibibabu-/p/18217048

相关文章

  • 如果任务过多,队列积压怎么处理?
    如果任务过多,队列积压怎么处理?1、内存队列满了应该怎么办2、问题要治本——发短信导致吞吐量降低的问题不能忽略!!3、多路复用IO模型的核心组件简介1、内存队列满了应该怎么办如图:大家可以看到,虽然现在发短信和广告投递,彼此之间的执行效率不受彼此影响,但是请......
  • netty建立数万客户端连接,并主动发消息
    @Slf4jpublicclassNettyClientTest{publicstaticvoidmain(String[]args)throwsException{EventLoopGroupworkerEventLoopGroup=newNioEventLoopGroup();try{Bootstrapbootstrap=newBootstrap();boo......
  • 消息队列练习题
    题目:要求进程A创建一条消息队列之后向进程B发送SIGUSR1信号,进程B收到该信号之后打开消息队列并把进程的PID作为消息写入到消息队列中,要求进程B在写入消息之后,发SIGUSR2信号给进程A,进程A收到该信号则从消息队列中读取消息并输出消息正文的内容。进程A的代码://构造用于接收消息......
  • 代码随想录算法训练营第三十七天 | 860.柠檬水找零、406.根据身高重建队列、452.用最
    目录860.柠檬水找零思路代码 406.根据身高重建队列思路代码452.用最少数量的箭引爆气球思路代码860.柠檬水找零本题看上好像挺难,其实挺简单的,大家先尝试自己做一做。代码随想录思路    这题还有什么难不难的,这道题不是非常经典的入门题吗。......
  • 系统编程练习题----使用消息队列实现两个进程之间的通信
    目录题目思路代码展示进程A进程B结果展示题目要求进程A创建一条消息队列之后向进程B发送SIGUSR1信号,进程B收到该信号之后打开消息队列并写入一段信息作为消息写入到消息队列中,要求进程B在写入消息之后,发SIGUSR2信号给进程A,进程A收到该信号则从消息队列中读取消息并输出消息正文......
  • 【ROS】-- 自定义回调队列
    在ros中,我们常用的回调处理是ros::spin()或者ros::spinOnce(),但是,这两个是阻塞式单线程处理的,即当不做其他处理的情况下,某一个回调函数堵塞,其他topic或者service的回调函数就无法进入。使用ros多线程的方式可以解决该问题,但引入多线程会导致线程安全的问题。针对某些场景,......
  • 【Azure Stream Analystics】流分析服务执行遇见警告错误消息,导致上游数据堆积,下游无
    问题描述AzureStreamAnalystics服务运行状态正常,测试输出也正常。但是下游没有任何数据产生。只是在概述页面中提示:Message:Encounterederrortryingtodiscovernewreferencedatasnapshot.Error:ThejobhasencounterederrorfromReferenceDatastorage.Error......
  • 互斥锁、进程间通信(IPC)、队列(queue)模块、队列实现进程间通信、生产者和消费者模型
    【一】互斥锁【1】什么是进程同步(互斥锁)互斥锁(Mutex)是一种用于多线程编程中控制对共享资源访问的机制。其作用是保证在同一时刻只有一个线程在访问共享资源,从而避免多个线程同时读写数据造成的问题。互斥锁的基本原理是在对共享资源进行访问前加锁,使得其他线程无法访问该......
  • Android Toast弹出消息在指定位置(setGravity)
    importandroid.widget.Toastimportandroid.view.Gravity默认Toast是显示在底部的,可以通过以下方法让其显示在顶部正中Toasttoast=Toast.makeText(SearchActivity.this,"取消关注失败",Toast.LENGTH_SHORT);toast.setGravity(Gravity.CENTER,0,0);toast.show();这样......
  • websocket实现消息实时通信
    后端代码实现1、导入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><version>3.2.5</version></dependency>2、创建websocket客户端对象。@Getter@Set......