首页 > 编程语言 >c++从零实现reactor高并发服务器!!!

c++从零实现reactor高并发服务器!!!

时间:2024-03-11 23:57:03浏览次数:27  
标签:const reactor int libxxx c++ char xx 服务器 main

环境准备

  1. linux虚拟机
  2. 安装升级c/c++编译器
  • gcc/g++ 选项 源代码文件1 源代码文件2 ... 源代码文件n
  • -o指定输出的文件名(不能和源文件同名 默认是a.out)
  • -g调试 -On链接时优化 减小体积(n=1-3) -c只编译 用于生成库
  • -std=c++11 支持c++11标准
  1. 安装man功能
  • man 级别 接口/命令
  • 级别: 1系统命令 2系统接口 3库函数 4设备文件 5文件 9内核
  1. 安装vscode c/c++插件 简体中文插件 Remote-ssh插件

基础知识

静态库动态库

  1. g++ -c -o libxxx.a xxx.cpp 生成了libxxx.a的静态库
  • g++ -o demo demo.cpp -L/path/xxx -lxxx -L指定路径 -l指定静态库名
  • 用静态库和用源代码是一样的,好处是可以隐藏源代码
  1. g++ -fPIC -shared -o libxxx.so xxx.cpp 制作动态库 调用方式同上
  • 用动态库必须先把目录加到LD_LIBRARY_PATH
  • 动态库是编译时不会连接到程序中,而是运行时装入,如果多个程序用到同一静态库,只在内存有一份(代码共享),避免空间浪费

**静态动态库都有 优先使用动态

makefile

每次编译都要g++ xxxx很麻烦,果然懒惰是第一生产力

# 指定编译的目标文件是生成这俩库
all:libxxx.a \
    libxxx.so

# 编译libxxx.a时,如果发现后面这俩文件变化了 重新编译
libxxx.a: main.h main.cpp
	g++ -c -o libxxx.a main.cpp+

# 同上
libxxx.so: main.h main.cpp
	g++ -fPIC -shared -o libxxx.so main.cpp

# make clean命令
clean:
		rm -f libxxx.a libxxx.so
  1. 增量编译,也就是说当前目录下有静态/动态了,就不编译这个了
  2. 用-I指定头文件包含路径
  3. g++前面是个tab,而不是八个空格
  4. main函数第三个是char* envp[] 打印出来效果如同env命令
  5. int setenv(const char* name, const char* value, int override) 环境变量名/值/是否替换 返回0成功-1失败(几乎不失败) 只对当前进程生效 进程终止下次就没有了,对shell无效

gdb调试

  1. yum -y install gdb 安装
  2. 编译时加-g 不要加-On
  3. gdb常用命令
  • set args xx xx xx 设置参数
  • break/b xx 在第某行打断点 (ctrl+g显示行号 或者vi下:set number)
  • run/r 一直运行直到断点
指令 用处 其他说明
set args xx xx 设置参数
break/b 20 在第20行打断点 ctrl+g 或 :set number
run/r 从头一直运行直到断点
next/n 执行当前语句 若为函数调用不进入
step/s 执行当前语句 进入(库函数由于无源码进不去)
continue/c 运行到下一个断点
print/p xx 查看变量/表达式的值 甚至可以p strlen(xx) p xx = 1
set var xx = xx 调试时设置参数
quit/q 退出gdb
  1. 出现段错误时(操作空指针) 程序会被内核强行终止,保存在core文件中(需要先ulimit -a 查看 core file size ulimit -c unlimited更改后才能看到)
  2. gdb demo core.123调试core文件 bt查看函数调用栈
  3. ps -ef|grep demo 查看进程号 gdb -p demo 123 会自动停止

linux

时间 <time.h>

  1. time_t
    typedef long time_t
  2. 获取1970/1/1到现在的秒数
    time_t now = time(0)
    time_t now; time(&now)
  3. tm结构体
    image
  4. 从time_t转tm结构体,注意加_r 线程安全
    localtime_r(&now, &tmnow)
    image
  5. mktime(&tm)把结构体转time_t
  6. gettimeofday(struct timeinterval* tv, struct timezone* tz) 获取1970/1/1到现在的秒数+当前的微秒数
    image
  7. sleep(秒) usleep(微秒)

目录操作<unistd.h>

  1. 获取当前目录
    char* getcwd(char* buf, size_t size)
    char* get_current_dir_name()
  • 相当于pwd,目录最大长度255 getcwd需要初始化一个256长度的字符数组,get_current_dir_name需要接free
  1. 切换目录
    int chdir(const char*path)

  2. 创建目录
    int mkdir(const char*pathname, mode_t mode)

  • mode如0755,不要省略0
  1. 删除目录
    int rmdir(const char*path)

<dirent.h> 读取目录相当于ls -a

DIR* opendir(const char* path); //打开目录
struct dirent*readdir(DIR* dirp); //读取目录
int closedir(DIR* dirp);        //关闭目录

image

  • 其中 d_type = 8 是文件,= 4 是子目录
    a
  1. 判断文件是否有某个权限,有返回0 没有返回-1
    int access(const char* path, int mode)

image

  1. stat结构体,有很多成员,比ls列出的还多
    int stat(const char*path, struct stat*buf)
    image

  2. 修改目录或文件的时间
    int utime(const char* path,const struct utimbuf* time)

  3. rename库函数 相当于mv
    int rename(const char* old, const char* new)

  4. remove库函数 相当于rm
    int remove(const char* path)

Linux系统错误 <errno.h>

  1. 获取错误代码的详细信息
    char* strerror(int errnum)
    int strerror_r(int errnum, char* buf, size_t buflen)

  2. 控制台显示最近一次系统错误的详细信息
    void perrpr(const char*s)

  • 不是系统调用的函数,不会设置errorno!!!!
  • 相当于出现error时,printf打印一下,但是error不会自动清零,所以一般是判断if (ret!=0) 也就是执行失败再去看错误

linux信号

可以用默认的信号操作(通常会终止进程) 也可以用signal函数自定义处理方式,但是有的信号不可被捕获、忽略 如9

sighandler_t signal(int signum, sighandler_t func)
void (*sighandler_t)(int);

  • 说明信号处理函数返回值void 入参int
  • func传入 SIG_IGN 表示忽略这个值的信号 SIG_DFL表示恢复默认
  • alarm(5); signal(14,func); 用于定时五秒发送闹钟信号(14)然后执行func函数~~ 注意 func中需要有alarm(5) 不然就只会处理一次咯!!

进程终止

  1. main函数运行完return
  2. 函数内调用exit() 会立即退出 不会返回调用它的地方
  3. _exit()和Exit()
  • exit() 不会调用局部变量的析构,但是会调用全局变量的析构,下面这俩直接终止不会析构
  1. 最后一个线程从线程主函数中返回
  2. pthread_exit()
  3. abort() 异常终止 、接收到信号、最后一个线程对取消请求作出响应
  • 终止状态就是main的return值 如果exit(n)就是n 异常终止是非零

atexit() 用于注册终止函数,最多注册32个

int main(){
   atexit(func1);
   atexit(func2);
   return 0; //正常return 或 exit 都会调用func1 func2
}

标签:const,reactor,int,libxxx,c++,char,xx,服务器,main
From: https://www.cnblogs.com/xsl-blogs/p/18061012

相关文章

  • 线段树(C++)
    线段树的本质就是树状数组,只不过线段树不再需要lowbit函数来定位对应数据的存储位置,取而代之的则是直接计算分叉结果位置。node结构体​ 通常而言,线段树所需要的存储空间约等于原数组的4倍。由于线段树需要存储区间的范围,所以我们需要自己定义一个新结构体来方便存储:constint......
  • (C++)树状数组和线段树的VSCode Snippet
    学都学了,肯定要往snippet里塞好东西嘛{ //Placeyoursnippetsforcpphere.Eachsnippetisdefinedunderasnippetnameandhasaprefix,bodyand //description.Theprefixiswhatisusedtotriggerthesnippetandthebodywillbeexpandedandinserted.......
  • 测试平台服务器安装docker
    1.安装docker:1.1.卸载旧版(如果没有可以跳过次步骤)sudoyumremovedocker\docker-client\docker-client-latest\docker-common\docker-latest\docker-latest-logrotate\docker-logrotate\docker-selinux\docker-engine-selinux\......
  • 用c++实现净现值的计算
    我是用c++实现的,我是把贴现率保留了四位小数。下面是我写的代码:#include<iostream>#include<cmath>usingnamespacestd;floatjst(intj,floatm,floatlv){while(j!=0){m*=(1+lv);j--;}return1.0/m;}i......
  • C++ 津津的储蓄计划
    描述津津的零花钱一直都是自己管理。每个月的月初妈妈给津津300元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同。为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里,到了年末她会加上20%还给津津。因此津津制定了一个储蓄计划:每个月的月初,在得到妈妈......
  • C++ 雇佣兵
    描述雇佣兵的体力最大值为M,初始体力值为0、战斗力为N、拥有X个能量元素。当雇佣兵的体力值恰好为M时,才可以参加一个为期M天的战斗期,战斗期结束体力值将为0。在同一个战斗期内,雇佣兵每连续战斗n天,战斗力就会上升1点,n为当前战斗期开始时的战斗力。一个战斗期结束后,雇佣兵需要用若......
  • 【Python使用】python高级进阶知识md总结第3篇:静态Web服务器-返回指定页面数据,静态We
    python高级进阶全知识知识笔记总结完整教程(附代码资料)主要内容讲述:操作系统,虚拟机软件,Ubuntu操作系统,Linux内核及发行版,查看目录命令,切换目录命令,绝对路径和相对路径,创建、删除文件及目录命令,复制、移动文件及目录命令,终端命令格式的组成,查看命令帮助。HTTP请求报文,HTTP响应报文......
  • [3] C++面向对象编程
    Day1函数指针数组简写函数指针typedeftypedefint(*FunPtr)(int,int);FunPtrFunArr[1]={Add};内联函数#pragmaregion内联函数//避免函数跳转对于程序的额外开销//有两种写法1).h中写实现文件(在.h中同时写声明和实现)//2)inline关键字......
  • C++学习笔记
    第一章认识C++1.1命名空间1.1.1命名空间的基本格式命名空间是一个由用户自己定义的作用域,在不同作用域中定义相同变量,不会冲突。命名空间中可以存放以下类型,这些定义/声明在结构体中的内容成为实体变量常量函数(可以是定义或声明)结构体类模板命名空间(可以嵌套定义)......
  • [转][SQL Server] 服务器可能资源不足,或者不信任该程序集
    参考:https://blog.csdn.net/u010109335/article/details/52668908参考:https://www.cnblogs.com/xiaoruilin/p/17054753.html已以用户NTSERVICE\SQLSERVERAGENT的身份执行。在尝试加载程序集ID65540时Microsoft.NETFramework出错。服务器可能资源不足,或者不信任该程序......