首页 > 系统相关 >linux C++程序测试命令的一种实现

linux C++程序测试命令的一种实现

时间:2024-04-12 15:57:43浏览次数:26  
标签:IPC int C++ 队列 ret 测试 linux id 消息

linux C++程序测试命令的一种实现

前言

在程序开发调试过程中,或者已经部署的情况下,我们常常需要执行一些测试命令。在命令行端输入命令,然后程序执行,说起来简单,但是当程序本身有很多终端调试信息输出时,命令输入很不方便。

针对上述问题,以下提供一个使用消息队列的命令行测试小工具代码实现。

1. 命令发送小工具实现代码

test_cmd_send.cpp

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

struct msgmbuf{/*消息的缓冲区结构*/
    long mtype; // 注意long与int的字长问题
    char mtext[50];
};

int main(){
	int ret = -1;
	int smsg_id ,rmsg_id;   /*收消息与发消息的队列id*/
	key_t key1,key2;        /*队列的键值*/

	struct msgmbuf msg_mbuf;/*创建消息缓冲区*/
    struct msgmbuf msg_revbuf;

    /*生成消息队列键值, 参数1为目录路径,目录必须已经存在*/
	key1 = ftok("/home/work_HLD",'a');
	key2 = ftok("/home/work_HLD",'b');

	if(key1 != -1 || key2 != -1)/*产生key成功*/
	{
		printf("成功建立KEY\n");		
	}
	else/*产生key失败*/
	{
		printf("建立KEY失败\n");		
	}

	smsg_id = msgget(key1, IPC_CREAT|0666); /*建立收消息的消息队列*/
	rmsg_id = msgget(key2, IPC_CREAT|0666);	/*建立发消息的消息队列*/

	if( -1 == smsg_id || -1 == rmsg_id)
	{
		printf("消息建立失败\n");
		return 0;		
	}	

	pid_t pid;
	pid = fork();/*通过fork()创建子进程,主进程进行发消息,子进程进行收消息*/

	while(1){
		if(pid != 0){/*主进程*/
            msg_mbuf.mtype = 10;/*设置发送的消息类型*/
            sleep(1);
            char content[50];

            memset(content, 0, 50);    
            printf("input x,y,θ,:\n");
            scanf("%s",content);/*用户输入内容*/
            if(strncmp(content,"end",3) == 0)/*如果前三个字符为end,则跳出循环*/
                break;
        
            memcpy(msg_mbuf.mtext, content, strlen(content));/*复制字符串*/
            ret = msgsnd(smsg_id, &msg_mbuf, strlen(content), IPC_NOWAIT);/*发送消息*/
            if( -1 == ret)
            {
                printf("发送消息失败\n");		
            }
		}
		else{/*子进程*/
            sleep(1);
			msg_revbuf.mtype = 10;/*设置收消息的类型*/
			ret = msgrcv(rmsg_id, &msg_revbuf, 50, 0, IPC_NOWAIT);/*接收消息*/
			if( -1 == ret)
			{
				/*可添加出错处理等*/
			}
			else
			{
				printf("执行结果:%s\n",msg_revbuf.mtext);	
			}
		}
	}

    msgctl(smsg_id, IPC_RMID,NULL);
	ret = msgctl(rmsg_id, IPC_RMID,NULL);/*删除收消息的队列*/
	if(-1 == ret)
	{
		printf("删除消息失败\n");
		return 0;		
	}
	return 0;
}


2. 被测试程序接收消息实现代码

main.c

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>


struct msgmbuf{/*消息的缓冲区结构*/
    long mtype; // 注意long与int的字长问题
    char mtext[50];
};

void test_cmd_run(Balcony_Spray *robot, int rid, int sid)
{
    if (rid == -1 || sid == -1 ) return;
    struct msgmbuf msg_mbuf;    /*创建消息缓冲区*/
    int ret = msgrcv(rid, &msg_mbuf, 50, 0,IPC_NOWAIT);/*接收消息*/\
    if( -1 == ret)
    {
        /*可添加出错处理等*/
    }
    else
    {
        string content(msg_mbuf.mtext);
        Rotating_Info("======>接收消息成功,长度:{}\n",ret);	
        Rotating_Info("content:{}\n",content);

        std::vector<string> string_split;
        boost::split(string_split, content, boost::is_any_of(","), boost::token_compress_on);
        if (string_split.size() >= 3)
        {
            //执行命令	
            //等待执行完成
           
            string result = "执行完成!";
            /*反馈运行结果*/
            ret = msgsnd(sid, result, result.size(), IPC_NOWAIT); 
        }
        
    }
}


int main(int argc, char **argv)
{
    int ret = -1;
    int rmsg_id = -1;                /*创建消息队列函数所用的标志位,以及收消息与发消息的队列id*/
    int smsg_id = -1;

	key_t key1 = -1;
    key_t key2 = -1;

	key1 = ftok("/home/work_HLD",'a');/*队列的键值*/
    key2 = ftok("/home/work_HLD",'b');/*队列的键值*/

	if(key1 != -1 && key2 != -1)/*产生key成功*/
	{
		rmsg_id = msgget(key1, IPC_CREAT|0666);	/*建立收消息的消息队列*/	
        smsg_id = msgget(key2, IPC_CREAT|0666);	/*建立发消息的消息队列*/	

        if (rmsg_id != -1 && smsg_id != -1) Rotating_Info("======>创建队列成功!");
	}
	else
    {
        Rotating_Info("======>创建队列失败!");
    }

    std::thread([dev_control, rmsg_id, smsg_id]() {
        while(1)
        {
            test_cmd_run(dev_control, rmsg_id , smsg_id);
            usleep(50*1000);
        }
    }).detach();

    while(1){ usleep(10*1000); };
    
    /*删除收消息的队列*/
    msgctl(rmsg_id, IPC_RMID,NULL);
    msgctl(smsg_id, IPC_RMID,NULL);
}

标签:IPC,int,C++,队列,ret,测试,linux,id,消息
From: https://www.cnblogs.com/HuangLiDi/p/18131471

相关文章

  • windows和Linux下路径表示
    reference一、\(Windows\)下的路径表示由于\(DOS\)原因,过去的\(windows\)路径表示采用反斜杠\,而路径字符串由于反斜杠的转义字符,因此需要用双反斜杠\\。\(Windows\)的根据路为磁盘号,后面跟:path如今的\(Windows\)内核在处理路径时同时支持正斜杠和反斜杠。但有时候......
  • C++陷阱—指定的返回类型的函数实际没有返回时会发生什么
    当一个string变量作为左值接收函数返回,当函数没有正确返回时,该string变量被如何构造?请看如下代码:#include<iostream>#include<string.h>usingnamespacestd;stringfoo(){if(0){return"youget";}}intmain(intargc,char**argv){......
  • C++编译器对溢出的默认处理
    C++编译器对溢出的默认处理在算数运算中,有一个比较头疼又必须要处理的事情:“溢出”,当我们有所疏忽,没有对溢出的情况做处理时,在我们不知情下就会产生很诡异的bug!那么当我们没有做溢出处理时,编译器的默认处理方式是什么呢?下面我们探究一下这个问题。测试环境Linux4.15.0#16.0......
  • C++观察者模式的实现
    C++观察者模式的实现观察者模式介绍观察者模式是软件设计模式里面一种很常用又很重要的一种设计模式,观察者模式又叫做发布-订阅(Publish/Subscribe)模式。也就是主题对象(subject)发布通知,订阅该主题的多个观察者(observer)可以收到通知从而更新自己。主题对象Subject发出通知时并不......
  • C++陷阱 — C++ auto变量类型推导
    问题描述C++使用auto类型声明一个单例对象的引用时,通过该auto变量来访问单例,是否等同于使用单例类::Instance()来访问单例呢?试看如下的例子:#include<stdint.h>#include<iostream>#include<string>#include<map>usingnamespacestd;classSingleClass{public:......
  • Linux服务器文件删除恢复方法XFS篇
    XFS文件系统文件被删除后,可以使用xfs_undelete工具进行恢复。值得注意的是:XFS文件系统的特性,文件删除后文件名即丢失,哪怕能恢复数据,文件名也恢复不了,所以在恢复之前一定要知道文件类型,最好还要知道创建时间、文件大小等信息,知道的越多越容易恢复。接下来安装xfs_undelete工具,以......
  • Linux使用ntp时间服务器同步时间
    NTP时间同步服务器是一种基于网络的时间同步协议,它的全称是NetworkTimeProtocol,NTP的主要功能是通过互联网将计算机的系统时间同步到标准的时间服务器上,以确保在分布式系统中的所有计算机都能有一个统一、准确的时间。一、使用ntp时间服务yumintall-yntp 二、启动并设......
  • 【Go】单元测试
    Go本身提供了一套轻量级的测试框架。符合规则的测试代码会在运行测试时被自动识别并执行。单元测试源文件的命名规则如下:在需要测试的包下面创建以“_test”结尾的go文件,形如[^.]*_test.goGo的单元测试函数分功能测试函数和性能测试函数,分别以Test和Benchmark为函数名前缀并以*t......
  • Linux0.12内核源码解读(2)-Bootsect.S
    大家好,我是呼噜噜,在上一篇文章聊聊x86计算机启动发生的事?我们了解了x86计算机启动过程,MBR、0x7c00是什么?其中当bios引导结束后,操作系统接过计算机的控制权后,发生了哪些事?本文将揭开迷雾的序章-Bootsect.S回顾计算机启动过程我们先来回顾一下,上古时期计算机按下电源键的启动过程,......
  • Linux安装Apollo配置中心
    apollo官网链接:https://www.apolloconfig.com/#/zh/READMEApollo组件简介ApolloConfigService是一个分布式的配置中心,主要负责应用的配置信息存储、推送和管理。ConfigService支持多种存储方式,例如本地文件系统、Git存储和数据库存储等,同时也提供基于轮询和通知两种方......