- 博客(45)
- 资源 (3)
- 收藏
- 关注
原创 搭建一个完整的cmake工程
假设有一个需要多个团队维护的大型项目,每个团队负责一个模块,那么如何使用cmake搭建该项目的cmake工程。本文提供了一种方法。假设一个团队维护的代码都放在module目录下,如果有多个团队,可以分别放moduleA、moduleB、moduleC等目录下。各个团队的对外头文件、第三方库、main函数放在public目录下。其中public/main目录下的cmake文件作为最顶层cmake文件。所有和构建相关脚本都放在public/build目录下,其中module.sh脚本用来将对应的模块编译成一个
2022-03-04 10:16:13
1958
原创 整理一些常用的shell脚本
1. for循环#! /bin/bashlists=(a b c d)for e in ${lists[@]};do echo ${e}done2. 文本替换#! /bin/bashsed -i 's/old_content/new_content/g' ${filename}3. 使用expect处理交互命令#! /usr/bin/expectset timeout 30set password "password"spawn ssh itran@11.22.
2022-03-03 22:05:41
819
原创 Linux常用调试工具总结
记录一些常用的linux调试工具1. gdblinux下代码调试工具2. nm$ nm a.out3. addr2line$ addr2line -C -f -e a.out 0x0000000000001149 # 通过地址解析到具体的文件和行号信息, a.out必须带调试信息4. strace # strace - trace system calls and signals $ strace -p [pid] -f -t -i -f 跟踪由fo
2022-03-03 16:09:03
2553
原创 vs code常用插件整理
记录一下常用的vs code插件vs code插件离线下载地址: https://marketplace.visualstudio.com/vscode0. C/C++ Extension PackPopular extensions for C++ development in Visual Studio Code1. C/C++C/C++ IntelliSense, debugging, and code browsing.2. Chinese (Simplified) (简体中文)
2022-02-23 14:07:03
1641
转载 Linux 后台开发常用调试工具
01 总览编译阶段nm 获取二进制文件包含的符号信息strings 获取二进制文件包含的字符串常量strip 去除二进制文件包含的符号readelf 显示目标文件详细信息objdump 尽可能反汇编出源代码addr2line 根据地址查找代码行运行阶段gdb 强大的调试工具ldd 显示程序需要使用的动态库和实际使用的动态库strace 跟踪程序当前的系统调用ltrace
2021-08-27 21:44:06
269
原创 shared_ptr智能指针
1. shared_ptr智能指针shared_ptr智能指针对一个对象采用共享所有权的机制来管理其生命周期,当对象的引用计数变为了0时shared_ptr才会析构其管理的对象一个shared_ptr的大小是裸指针的两倍,因为其内部包含了两个指针,一个指向该对象的裸指针,另一个是指向该对象的引用计数的裸指针1.1 通过一个示例简单了解shared_ptr的基本用法#include <iostream>#include <memory>using namespace
2021-07-10 18:45:10
231
1
原创 简单了解c++开源测试框架googletest
GTest(googletest)是Google开发的一款开源的c/c++测试框架。项目地址:https://github.com/google/googletest1. 一个简单的例子#include <iostream>#include "gtest/gtest.h"using namespace std;int divfunc(int a, int b) { return (b) ? a / b : __INT_MAX__; }TEST(CalculatorTestSe
2021-06-30 20:10:50
446
原创 使用gcov+lcov工具可视化代码分支覆盖率数据
通过一个简单的例子,来展示如何使用gcov+lcov来生成代码分支覆盖率数据并将其图形化显示假设有一个main.cpp文件1. 首先使用gcc编译该文件g++ main.cpp -fprofile-arcs -ftest-coverage -l gcov -o main.out # ftest-coverage用以生成.gcno文件,fprofile-arcs用来在后面应用程序时生成.gcda文件此时会生成以下两个文件:main.gcnomain.out2. 执行main.out文件此
2021-06-28 19:18:51
1849
原创 c++实现线程池
线程池技术是为了避免频繁的创建和销毁线程所带来的开销。线程池是一个典型的生产者-消费者模型,用户将要执行的任务添加到任务队列,并通知线程池,线程池则唤醒其中的一个线程来处理任务。一个简单的c++线程池实现如下所示:#include <iostream>#include <vector>#include <deque>#include <thread>#include <mutex>#include <condition_vari
2021-05-22 16:27:50
2329
3
原创 GNU C中的__attribute__关键字
__attribute__机制是GNU C中一个非常有用的特性,它可以用来修饰函数、变量和结构体的编译器属性。__attribute__((noinline)) /* 设置函数为非内联函数 */ __attribute__((always_inline)) /* 设置函数内联 */__attribute__((weak)) /* 用来声明weak function */__attribute__((aligned(4))) /* 设置字节对齐 */__attribute__((packe
2021-04-13 10:04:32
474
原创 c++显示实例化和显示具体化
1. 实例化(instantiation)实例化是指编译器使用函数(或者是类)模板为特定类型生成函数(类)定义。编译器不会为函数(或者类)模板生成定义,只有当我们为函数(或者类)模板指定了一个特定类型时,编译器才会生成。编译器为特定类型的函数(或者类)模板生成定义的行为被称为实例化。template<typename T>void Swap(T & a, T & b){ T temp = a; a = b; b = temp;}void us
2021-03-31 22:48:17
2082
原创 docker容器(5)——卷与持久化
每个docker容器在创建的时候都被自动分配了本地存储,这是容器中的文件默认存储的地方,在Linux系统中,该存储目录位于/var/lib/docker/<storage-driver>之下。存储在其中的数据的生命周期通常和容器相同,当删除容器时这些数据也就被删除掉了。只有那些被保存在卷上的数据可以被保存下来,这是因为卷和容器是解耦的,从而可以独立的创建和管理卷。1. 查看容器卷docker volume ls# 查看卷的详细信息docker volume inspect <vo
2021-03-14 19:02:32
147
原创 docker容器(4)——网络
1. 单机桥接网络docker网络架构源自一种叫做容器网络模型(CNM)的方案。Libnetwork库是Docker对CNM的一种实现,提供了Docker核心网络架构的全部功能。单机桥接网络是最简单的Docker网络,它只在单个docker主机上运行,并且只能与所在docker主机上的容器进行连接。2. 查看docker主机上的桥接网络每个Docker主机都有一个默认的单机桥接网络,在Linux上网络名称为bridge。# 查看当前主机上的docker网络docker network ls#
2021-03-14 18:47:34
139
原创 docker容器(3)——镜像操作
1. 查看镜像docker images 列出本地主机上的所有镜像eg. docker images ubuntu 只列出名称相同但标签不同的镜像2. 搜索镜像docker search <image name>3. 拉取镜像使用docker pull可以从镜像仓库中拉取指定的镜像到本地主机上。docker pull <image name>eg. docker pull ubuntu:latest4. 删除镜像docker
2021-03-14 18:22:55
102
原创 docker容器(2)——容器操作
1 查看容器 docker ps [OPTIONS] -- OPTIONS说明: -a :显示所有的容器,包括未运行的。 -f :根据条件过滤显示的内容。 --format :指定返回值的模板文件。 -l :显示最近创建的容器。 -n :列出最近创建的n个容器。 --no-trunc :不截断输出。 -q :静默模式,只显示容器编号。 -s :显示总的文件大小。2 创建新的容器并运行一个命令 docker run <
2021-03-14 18:12:08
151
原创 docker容器(1)——简介
1. 虚拟机和容器业务是基于应用的,而大部分应用是运行在服务器之上的。以前,每个服务器上只能运行一个应用,因为无论是windows还是linux操作系统,都没有相应的技术手段来保证在一台服务器上稳定而安全地同时运行多个应用。虚拟机技术解决了这一问题,从而可以将多个应用稳定、安全地同时运行在一个服务器之上。但是,虚拟机技术也有不足——太消耗资源(cpu、RAM、存储),其根本原因在于每个虚拟机都包含了一个专用的操作系统。容器和虚拟机的功能相似,最大的区别在于容器更快且更轻量级,因为运行在同一个服务器上的容器
2021-03-14 18:05:37
208
原创 使用git alias提高代码开发效率
当我们进行代码开发时,难免会经常输入git branch -vv、git checkout、git commit等命令,通过配置home目录下的.gitconfig文件能够为这些命令设置别名,从而简化命令,解放我们的双手[alias]st = statusci = commitco = checkoutcp = cherry-pickbr = branch -vvre = remote -vvrb = rebaselg = log --pretty=format:%‘h - %<(1
2021-03-10 20:40:56
136
原创 #、##、__VA_ARGS__
1. #运算符#预处理运算符可以把参数转换成字符串#define SQRT(x) printf("the square of "#x" is %d\n", ((x)*(x)))int main(){ SQRT(3); return 0;}/* output: the square of 3 is 9 */2. ##运算符##运算符可以把两个几号组合成一个记号#define XNAME(n) x ## nXNAME(1)则会被组合成一个新的记号: x13. __VA_AR
2021-03-02 20:07:28
197
原创 守护进程(daemon)
守护进程是一种生命周期很长的进程。它在后台长期运行,并且没有控制终端。1. 创建守护进程的步骤step1. 设置权限掩码清除进程的umask,从而确保守护进程有足够的权限来创建文件和目录。umask(0);step2. fork子进程并退出父进程int pid = fork();if (pid > 0) exit(0);有两个原因需要我们这样做。首先,如果daemon进程是通过shell命令启动的,当我们退出父进程时,shell会认为命令已经执行完了,从而使得子进程继续在后台运行;
2021-02-21 22:36:10
326
原创 libevent事件通知库学习笔记
libevent是一个基于reactor模式的开源事件通知库,具有高性能、轻量级等优点。本文分享了对libevent 1.4源码的一些理解。1. libevent使用实例——event-testlibevent 1.4源码提供了一些使用实例,本文通过对其中的一个实例,来分析libevent库是如何实现事件通知功能的。以下源码取自sample/event-test.c,为了便于阅读,删除了关于WIN32的代码,去掉了对返回值的错误判断。/* * event-test.c * Compile with
2021-02-20 19:26:01
307
原创 Linux系统日志 rsyslogd
Linux系统日志 rsyslogdrsyslogd是linux系统提供的一个守护进程,用来处理系统日志。rsyslogd守护进程既能够接受用户进程输出的日志,也能够接受内核日志。ispurs-virtual-machine:~$ ps aux | grep rsyslogdsyslog 6033 0.0 0.0 256588 3328 ? Ssl 2月18 0:00 /usr/sbin/rsyslogd -n1. syslog函数用户进程可以通过syslog函
2021-02-19 00:28:26
1415
原创 ELF格式文件
1. ELF格式ELF(Executable Linkable Format)格式是Linux中的可执行文件格式。在Linux中,可执行文件、目标文件、动态链接库(linux的.so)、静态链接库(linux下的.a文件)都是ELF格式的文件。ELF文件标准里面把ELF格式文件分为了4类。可重定位文件(relocatable file)、可执行文件(executable file)、共享目标文...
2020-04-29 23:16:54
1311
原创 程序的机器级表示
本文对《深入理解计算机系统》(第三版)中第三章——“程序的机器级表示”中的部分内容进行了整理,以方便日后查阅。目录1.整数寄存器2. 操作数3. 数据传送指令——MOV类。4. 压入和弹出栈数据——PUSH操作和POP操作5. 算术和逻辑操作6. 条件码7. 比较和测试指令——CMP和TEST8. SET指令9.JMP跳转指令1.整数寄存器一个...
2019-09-01 17:18:51
361
原创 类型转换运算符
1、为什么需要类型转换运算符下面的程序中的类型转换是被编译器允许的,但是这是一个没有意义的转换。为了避免这种情况发生,C++中对类型转换进行了更加严格的限制。struct Data{ int data[100]; };Data d = { 1, 2.5, 23 };char * p = (char *)(&d); // 类型转换,转换成字符串 2、C++中的类...
2018-09-05 21:47:47
277
原创 组合问题和全排列
1.组合问题问题描述:从n个元素中选出k个元素,列出所有可能的情况template<typename T>void combineCore(vector<T> data, int n, int k, int start, vector<T> & v, vector<vector<T>> & res){ if...
2018-09-05 21:40:57
359
原创 二叉树
一、二叉树的定义二叉树(Binary Tree)是n(n>= 0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根节点和两颗互不相交的、分别称为根节点的左子树和右子树的二叉树组成。/*二叉树的二叉链表存储表示*/typedef struct BiTNode{ int data; struct BiTNode * left, * right; BiTNode(int ...
2018-07-10 09:58:27
541
原创 int类型转成string类型
方法一: 使用sprintf函数/********************************************************* sprintf** c库函数 头文件:<stdio.h> ** int sprintf ( char * str, const char * format, ... );** 作用:发送格式化输出到 str 所指向的字符串*...
2018-07-06 15:17:55
2433
原创 名字与地址转换相关函数
===============================================================#include <netdb.h>struct hostent *gethostbyname(const char * hostname);--作用 查找主机名。当调用成功时,返回一个指向hostent结构 的指针,该结构中含有所查找主机的所有IPv4地址--...
2018-06-22 14:49:49
217
原创 SCTP客户/服务器程序编译过程中遇到的问题
问题1:关于IPPROTO_SCTP的报错解决方法:在/usr/include/netinet/in.h和/usr/include/netinet/sctp.h中都对IPPROTO_SCTP进行了定义,导致编译报错 将sctp.h中的IPPROTO_SCTP的定义注释掉就好了 #define IPPROTO_SCTP 132问题2:...
2018-06-19 16:52:05
1367
原创 SCTP客户/服务器程序
/* SCTP一到多式流分回射服务器程序 *//* server.c */#include "wrapper.c"#define SERV_PORT 8888#define LISTENQ 128int main(int argc, char **argv){ int sockfd, msg_flags; // msg_flags参数中存放可能有的消息标志 char buf[B...
2018-06-19 16:28:18
465
原创 SCTP套接字编程—结构体和函数
1. sctp_sndrcvinfo结构体2. sctp_event_subscribe结构体3. SCTP套接字编程相关函数
2018-06-19 16:24:04
501
原创 位运算符实现整数乘法运算
看了一些关于用逻辑运算实现乘法的博客,但是看完后感觉还是不太明白是如何实现的。最后只能按照自己的想法用逻辑运算符实现了乘法运算。从3*7=21的二进制计算过程可以看出,其最终结果可以看成是01100,00110, 00011三个二进制数之和。仔细观察可以发现,这三个二进制数字分别是011(十进制数3)向右移动不同位数后的结果。所以我的方法是: 对于两个相乘的整数a和b, 先用一个vector<...
2018-06-17 23:23:46
1232
原创 UDP回射客户/服务器程序
// UDP服务器端// server.c#include "wrapper.c"#include <string.h>#include <arpa/inet.h>#include <sys/types.h>#define SERV_PORT 7777int main(void){ int listenfd; ssize_t n; so...
2018-06-14 17:23:20
338
原创 详解fork()函数
一、函数定义 #include <unistd.h> pid_t fork(void); 返回值: 子进程返回0,父进程返回子进程ID,出错返回-1调用fork函数创建新的进程(子进程,child process)。fork函数被调用一次,但是返回两次。其中,子进程的返回值是0,父进程的返回值是新建子进程的进程ID。调用fork函数创建子进程后,子进程和...
2018-06-13 09:00:25
1200
原创 常见的7种排序算法
1、冒泡排序最简单的一种排序算法。假设长度为n的数组arr,要按照从小到大排序。则冒泡排序的具体过程可以描述为:首先从数组的第一个元素开始到数组最后一个元素为止,对数组中相邻的两个元素进行比较,如果位于数组左端的元素大于数组右端的元素,则交换这两个元素在数组中的位置,此时数组最右端的元素即为该数组中所有元素的最大值。接着对该数组剩下的n-1个元素进行冒泡排序,直到整个数组有序排列。算法的时间复...
2018-06-10 11:37:21
317826
26
原创 一个简单的返回大写字母的服务器程序
/* myserver.c */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <arpa/inet.h>#include <sys/types.h>#include <sys/socket.h>#include <unist...
2018-06-06 16:28:17
488
1
原创 字节序转换函数和地址转换函数
-- 字节序转换函数主机一般采用小端字节序(也有采用大端字节序的),网络数据流采用大端字节序,为使同样的代码在大端和小端计算机上编译后都能正常运行,可以调用字节序转换函数做网络字节序和主机字节序的转换。 当使用这些函数时,我们并不关心主机字节序和网络字节序的真实值(或为大端,或为小端) 。我们所要做的只是调用适当的函数在主机和网络字节序之间转换某个给定值。-- 地址转换函数...
2018-06-06 15:08:35
822
原创 查看主机字节序
/************************************************** * 输出主机字节序 * 小端字节序(little-endian) 低序字节存储在起始地址(低地址) * 大端字节序(big-endian) 高序字节存储在起始地址 * ----------------------------------------------- * 0x0102 ...
2018-06-06 11:01:53
1399
原创 关于时间获取的C/S模型
/* wrapper.c */#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <sys/types.h> #include <sys/socket.h>voidperr_exit(const char * s) { per...
2018-06-06 10:55:54
297
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人