
c/c++
编程小耗子
本人比较喜欢高性能服务器开发。
在校曾获奖:
中国大学生计算机设计大赛国赛三等奖;
龙鼎杯河北二等奖;
蓝桥杯省赛三等奖;
CCPC河北省赛三等奖;
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
physx中ray不碰撞某些物体的方法
设置过滤类型const PxFilterData collisionGroupIgnore(0, 0, 0, 1); // 碰撞会被忽略的组const PxFilterData collisionGroup(1, 0, 0, 0); // 需要碰撞的组给shape设置类型void setShapeFilterData(PxRigidActor * actor, PxFilterData &data){ PxShape* shapes = NULL; actor->getSh原创 2021-05-28 19:19:22 · 533 阅读 · 0 评论 -
判断位置是否会发生碰撞
核心函数整理physx的函数解释在下面。// 从actor中获取第一个shapePxShape * getShapeByActor(PxRigidActor *actor){ if (!actor) return NULL; const PxU32 numShapes = actor->getNbShapes(); if (numShapes <= 0) { cout << "test Shape num is <= 0" << endl原创 2021-05-28 19:17:32 · 683 阅读 · 0 评论 -
在physx中创建射线raycase,并获取碰撞点
给物体创建射线ray通过raycastSingle函数去获取发射的射线是否会碰到物体,不需要特殊处理的可以不使用回调。不用回调的版本// origin是起点, unitDir是方向int RayCaseSingle(PxVec3 &origin, PxVec3 &unitDir){ PxRaycastHit hitInfo; // 返回的点,法向量信息等都在这里 PxReal maxDist = FLT_MAX; // 最大射线距离 //PxHitFlag::eMESH_AN原创 2021-05-25 18:10:21 · 684 阅读 · 1 评论 -
physx中加载obj创建mesh的方法
如何加载三角片面的obj文件到physx中obj中的会在physx中的重要内容介绍在obj文件中,physx加载PxTriangleMeshDesc最终要的两个数据,一个是顶点信息,一个是三角片面的三个顶点索引。相对的obj中,这个顶点信息在obj文件中是每行v开头的后面的数据,分别代表 x,y,z。例如v 3.419436 0.06810839 -1.137559 ,x= 3.419436, y=0.06810839 , z= -1.137559面的信息是f打头的数据,数据如下:f 1598原创 2021-05-24 18:31:29 · 1025 阅读 · 3 评论 -
physx中判断actor是否会发生碰撞
一、物理碰撞模拟方法通过模拟一个真实的碰撞,但是不体现碰撞的特性,通过回调的方式来获取到对应的actor的指针来判断是否碰撞,但是要忽略掉当前的碰撞。设置分类const PxFilterData collisionGroupIgnore(0, 0, 0, 1); // 分类自己怎么定义都可以设置形状shape中的分类,方便在filtershape函数中做过滤PxRigidDynamic* createIgnoreDynamic(const PxTransform& t, cons原创 2021-05-24 17:50:40 · 814 阅读 · 0 评论 -
c++ chrono库做时间统计,毫秒级别封装
参考博客https://www.cnblogs.com/jinxiang1224/p/8468162.html根据chrono库的,封装一个毫秒级别的时间统计函数当然,这个库最高可以统计到纳秒级别封装#include <iostream>#include <chrono> namespace { typedef std::chrono::steady_clock STEADY_CLOCK; STEADY_CLOCK::time_point t1 = STEADY原创 2021-05-07 17:53:58 · 839 阅读 · 0 评论 -
时间轮算法设计实现
时间轮算法基本思想参照时钟运转的思路,每个相同刻度下的时间是相同的,将所有相同时间的时间放在一个槽中,通过用一个指针每过一个刻度指向时间轮的槽,取出槽中链表,循环遍历相同刻度下的事件。(liunx内核就是这么做的)。如图所示的是一个时间轮的基本结构。时间轮分为N个时间槽slot,每时间槽指向一个定时器链表,这个链表里包含多个定时器,这个链表的定时器Timeout时间相同,因此链表里的定时器无须排序。简单时间轮的实现#include <unistd.h>#include <i原创 2021-01-25 22:31:15 · 408 阅读 · 0 评论 -
使用红黑树实现定时器
使用红黑树实现定时器使用的是nginx中使用的红黑树结构,直接从中迁移出来并修改。通过红黑树实现的时间轮,查询与插入的时间复杂度是O(Logn)。查询第一个节点只需要找树的最左边一个节点即可。定时器本身就是从头部开始取数据,红黑树就不比跳表这一数据结构匹配定时器实现的更好。文件rbtree.h#ifndef _NGX_RBTREE_H_INCLUDED_#define _NGX_RBTREE_H_INCLUDED_typedef unsigned int ngx_rbtree_ke原创 2021-01-25 21:19:19 · 979 阅读 · 0 评论 -
使用跳表实现定时器
使用跳表实现定时器使用的是redis中使用的跳表结构,直接从中迁移出来并修改。通过跳表实现的时间轮,查询第一个数据的时间复杂度就是O(1),插入时间复杂度就 大概率的趋向于O(logn(N))。定时器本身就是从头部开始取数据,跳表这一数据结构就特别匹配定时器的实现。文件skiplist.h#ifndef _MARK_SKIPLIST_#define _MARK_SKIPLIST_/* ZSETs use a specialized version of Skiplists */#def原创 2021-01-25 09:01:52 · 688 阅读 · 0 评论 -
数据离奇消失bug------栈覆盖
* 工作中遇到的bug,当时写了一块内存后,其他内存的数据消失了,百思不得其解,后来想到会不会是栈内存覆盖,一看还真是。于是就有了这篇文章。* 在通过栈申请的内存有一个特点,他是连续的,这就很容易造成一个现象,如果出现栈溢出问题,会覆盖写掉其他变量的东西。比如我下面写的例子。```c#include <stdio.h>#include <stdlib.h>#include <string.h>char bigmem[50] = {0};void mai原创 2021-01-20 23:36:04 · 417 阅读 · 0 评论 -
通过fd链接去获取相应的本地地址和远端地址
## 通过fd链接去获取相应的本地地址和远端地址```cint get_ip_and_port_by_fd(int fd, char* local_ip, int* local_port, char* peer_ip, int* peer_port){ if((!local_ip || !local_port) && (!peer_ip || !peer_port)){ printf("ip or port mem is null\n");...原创 2021-01-20 23:35:10 · 921 阅读 · 1 评论 -
md5从16字节转换为32字节
## md5从16字节转换为32字节16字节到32字节的转换,实际上是通过将每个字节输出成十六进制数据的来的,所以通过一下函数实现。```c#include <stdio.h>void md5_short_to_long(char *md5_long, char *md5_short){ int i = 0; char *p_md5_long = md5_long; for(i = 0; i < MD5_SHORT; i++){ ...原创 2021-01-20 23:34:17 · 1263 阅读 · 0 评论 -
相同指针与全局变量编译之坑
相同指针陷阱这是一个将yp指针的值加到xp指针两次的函数。void fun1(int *xp, int *yp){ *xp += *yp; *xp += *yp;}这个代码表面一看可以优化成这样void fun1(int *xp, int *yp){ *xp += 2 * *yp;}但是如果yp于xp指针指向的是同一个地址,那么情况就会变成这样,此时*xp的结果会是原先的4倍。void fun1(int *xp, int *yp){ *xp += *xp; *xp +=原创 2020-11-27 14:38:21 · 290 阅读 · 0 评论 -
多线程的虚假唤醒理解
虚假唤醒在多线程环境中,在竞争资源的时候,有时候拿到了锁,却发现资源没了,这可能就是使用了条件等待产生的一个惊群效应。pthread_cond_signal将所有的pthread_cond_wait线程都唤醒了,但是只有个别线程竞争到了资源,没有竞争资源的线程就是属于虚假唤醒的线程。对于虚假唤醒的线程需要做特殊判断,在获取到mutex锁后,要去判断资源是不是为空,是空就是虚假唤醒,继续睡眠。是否有可能多个线程同时读到一个数据的情况呢?这就要从pthread_cond_wait函数的实现讲起。原创 2020-11-20 21:20:52 · 387 阅读 · 1 评论 -
字符串匹配sunday算法封装
字符串匹配在工作中,需要用字符串匹配,为了可以快速切换不同的库,编写了这个匹配接口,方便实现不同字符串匹配库的切换.接口封装sunday.h#include<stdio.h>#include<string.h>#include <stdlib.h>#define KEYWORD_SHIFT_LEN 256 #define KEYWORD_MAXLEN 32 // 最大长度#define KEYWORD_DEFAULT 32原创 2020-11-20 21:19:07 · 333 阅读 · 0 评论 -
hyperscan字符串匹配库接口封装
字符串匹配在工作中,需要用字符串匹配,为了可以快速切换不同的库,编写了这个匹配接口,方便实现不同字符串匹配库的切换.接口封装头文件 kwmatch.h#ifndef __KWMATCH_H__#define __KWMATCH_H__// control log print switch#define KW_DEBUG 1#if KW_DEBUG#define __DEBUG(p,...) printf("[FILE:%s,FUNC:%s,Line:%d]"p"\n",__F原创 2020-11-18 23:08:21 · 1214 阅读 · 5 评论 -
将rgba图片信息转换为bmp图片文件
将rgba图片信息转换为bmp图片文件#include <stdio.h>#include <windows.h>#pragma pack(1)//BMP文件头(14字节)typedef struct /**** BMP file header structure ****/{ unsigned int bfSize; /* Size of file */ unsigned short bfRes原创 2020-11-18 23:07:10 · 1611 阅读 · 0 评论 -
使用二级指针申请链表
使用二级指针申请链表#include <stdio.h>typedef struct Node_t{ int id; struct Node * next;}Node;void main(){ Node * nodeList = NULL; Node * tmp = NULL; fun(&nodeList ,10); tmp = nodeList; while(tmp){ printf("tmp:%d\n",tmp->id); tmp = tmp-&原创 2020-11-18 23:05:07 · 187 阅读 · 0 评论 -
nginx中的链表遍历
nginx中的链表遍历#include <ngx_list.h>void main(){ // 创建链表 ngx_list_t* testlist = ngx_list_create(r->pool, 4,sizeof(ngx_str_t)); if (testlist == NULL) { return NGX_ERROR; } // 加入一个元素,返回元素指针 ngx_str_t* str = ngx_list_p原创 2020-11-18 23:01:03 · 252 阅读 · 0 评论 -
将字符的编码转换为另一种编码
将字符的编码转换为另一种编码int code_convert(char *from_charset,char *to_charset,char *inbuf,size_t inlen,char *outbuf,size_t outlen) { iconv_t cd; //int rc; char **pin = &inbuf; char **pout = &outbuf; printf("+++++peng from:%s原创 2020-11-18 23:00:12 · 364 阅读 · 0 评论 -
将线程绑定在指定的CPU上运行
将线程绑定在指定的CPU上运行void main(){ int cpu_num = sysconf(_SC_NPROCESSORS_CONF); pthread_t tid; cpu_set_t mask; cpu_set_t get; CPU_ZERO(&mask); CPU_ZERO(&get); // 绑定在第三个cpu核心上 CPU_SET(3, &mask); pthread_create(&tid, NULL, f_thread, (voi原创 2020-11-18 22:59:25 · 640 阅读 · 0 评论 -
设置core大小限制为不限制
设置core大小限制为不限制int set_corefile_limit(void){ struct rlimit limit; limit.rlim_cur = RLIM_INFINITY; limit.rlim_max = RLIM_INFINITY; if (setrlimit(RLIMIT_CORE, &limit)) { printf("set limit core file failed\n"); return -1; } return 0;}...原创 2020-11-18 22:58:26 · 781 阅读 · 0 评论 -
判断指定pid号的进程是否存在
判断指定进程是否存在// 存在返回1int process_exist(char *pid){ int ret = 0; char pid_path[64] = {0}; struct stat stat_buf; if(!pid) return 0; snprintf(pid_path, 64, "/proc/%s/status", pid); if (stat(pid_path, &stat_buf) == 0) ret = 1; return ret;}原创 2020-11-16 23:15:05 · 1519 阅读 · 0 评论 -
初始化消息队列
初始化消息队列static int init_msq_master(char *ipcpath, int clean){ struct msg_buf msg; int msqid = -1, ipckey = -1; int ret = -1; int msglen = 4096; /* 为建立IPC通讯准备key值。注意: 1、使用ftok时,文件必须存在; 2、要想确保每次获得key值不变,文件不能被删除; 3、第2个参数表示子序号,只能为8bits(1-255,must原创 2020-11-16 23:13:32 · 480 阅读 · 0 评论 -
linux系统中创建共享内存
创建共享内存//创建共享内存int init_shmget_master(char* ipcpath, unsigned int shm_size){ int ret = -1, ipckey = -1; struct shmid_ds shm_stat; void *shm = NULL; /* 为建立IPC通讯准备key值。注意: 1、使用ftok时,文件必须存在; 2、要想确保每次获得key值不变,文件不能被删除; 3、第2个参数表示子序号,只能为8bits(1-255,原创 2020-11-16 23:12:46 · 287 阅读 · 0 评论 -
获取指定pid使用内存情况
获取指定pid使用内存情况int get_task_mem(int pid){ long mem = 0; FILE * p_file = NULL; char cmd[512]={0},fpath[128]={0},buf[128]; if (pid==0) return 0; sprintf(fpath,"/proc/%d/statm",pid); if (access(fpath,R_OK)) return 0; sprintf(cmd,"cat %s |awk '原创 2020-11-16 23:11:34 · 881 阅读 · 0 评论 -
获取结构体中变量的偏移位置
获取结构体变量偏移位置#define get_variable_index(TYPE, member,ITYPE,index)\{ \ *index = (ITYPE)(&(((TYPE*)0)->member));\}while(0)TYPE为结构体类型。member为结构体中要获取位置的变量名。ITYPE为接收偏移的变量的类型。index为接收偏移的变量。使用范例#include <stdio.h>struct temp { char原创 2020-11-16 23:08:55 · 950 阅读 · 0 评论 -
数据结构之快速排序的三种写法
方法1:前面放一个指针的方法void quick(int *arr, int len, int start, int end){ int low = start; for (int i = start + 1; i < end + 1; i++) { if (arr[i] < arr[start]){ low++; if (low != i){ swap(&arr[low], &arr[i]); } } } swap(&ar原创 2020-11-16 22:56:53 · 350 阅读 · 0 评论 -
如何编写operator =(老鸟与菜鸟写法)
类前提概要class CMyString{public: CMyString(char* pData = nullptr); CMyString(const CMyString& str); ~CMyString(void); CMyString& operator = (const CMyString &str);private: char* m_pData; };赋值的最常规写法:CMyString& CMyString::operator =原创 2020-11-16 22:55:17 · 588 阅读 · 0 评论 -
QT02-------控件与对话框的使用
QMainWindow菜单栏菜单栏最多有一个//菜单栏创建QMenuBar * bar = menuBar();//将菜单栏放入到窗口中setMenuBar(bar);//创建菜单QMenu * fileMenu = bar->addMenu("文件");//创建菜单项QAction * newAction = fileMenu->addAction("新建");//添加分割线fileMenu->addSeparator();工具栏工具栏可以有多个//新建工原创 2020-11-16 22:52:55 · 319 阅读 · 0 评论 -
结构体实现业务与代码的分离
将结构体的指针实现与业务分离#define KEY_VALUE int#define BSTREE_ENTRY(name, type) \ struct name{ \ struct type *left; \ struct type *right; \ } struct bstree_node{ KEY_VALUE data; BSTREE_ENTRY(,bstree_node) bst;};typedef struct _rbtree { bstre原创 2020-11-16 22:28:57 · 255 阅读 · 0 评论 -
指针常量,常量指针区分方法
口诀变量类型先去掉,const 的右边是什么,那么什么就不变。解释比如const char *p的先去掉类型,那就是const *p,然后const的右边有*p,而p是一个指针,*p是指针的解引用,那就是该指针的解引用内容不变。在比如char* const p,const的右边是p,而p是什么?是一个指针,那说明这就是指针不变,也就是该指针指向的地址不能变化,只能赋初值。...原创 2020-08-21 10:24:09 · 200 阅读 · 0 评论 -
tcp udp数据报定义结构体
文章链接:https://codemouse.online/archives/2020-06-30-21-08-22tcp udp数据报定义结构体由于结构体写在结构体里面容易出现结构体内存对齐问题,需要将对齐值改为1,防止出错。#pragma pack(1) //设置对齐数udp报文头定义:struct udphdr { unsigned short sport; unsigned short dport; unsigned short length; unsigned s原创 2020-06-30 21:09:43 · 702 阅读 · 0 评论 -
高性能服务器---内存池设计
文章链接:https://codemouse.online/archives/2020-06-26-23-50-33内存池在日常的写代码中,经常有需要申请内存的时候,但是频繁的申请释放会特别的浪费时间,于是衍生了内存池,由内存池帮忙管理内存,内存池帮忙统一释放,免去了用户的频繁释放,申请内存只需要从内存池中已经申请好的内存中取出,如果没有大于需求的内存,则内存池再去申请一块回来。内存池增强了程序员对内存碎片话的管理,加快了内存的使用速度。这个内存池的模型是参考了nginx内使用的内存池,相当于一个简原创 2020-06-30 20:43:42 · 308 阅读 · 0 评论 -
protobuf安装及其简单使用
文章链接:https://codemouse.online/archives/2020-06-22163236protocol buffers 是什么?Protocol buffers 是一种语言中立,平台无关,可扩展的序列化数据的格式,可用于通信协议,数据存储等。Protocol buffers 在序列化数据方面,它是灵活的,高效的。相比于 XML 来说,Protocol buffers 更加小巧,更加快速,更加简单。一旦定义了要处理的数据的数据结构之后,就可以利用 Protocol buffer原创 2020-06-24 23:31:22 · 528 阅读 · 0 评论 -
OpenSSL库之内存分配
文章链接:https://codemouse.online/archives/2020-06-20223142内存分配用户在使用内存时,容易犯的错误就是内存泄露。当用户调用内存分配和释放函数时,查找内存泄露比较麻烦。OpenSSL提供了内置的内存分配/释放函数。如果用户完全调用OpenSSL的内存分配和释放函数,可以方便的找到内存泄露点。OpenSSL分配内存时,在其内部维护一个内存分配哈希表,用于存放已经分配但未释放的内存信息。当用户申请内存分配时,在哈希表中添加此项信息,内存释放时删除该信息。当用原创 2020-06-24 23:30:44 · 643 阅读 · 0 评论 -
OpenSSL库之哈希表
文章链接:https://codemouse.online/archives/2020-06-20175758哈希表在一般的数据结构如线性表和树中,记录在结构中的相对位置是与记录的关键字之间不存在确定的关系,在结构中查找记录时需进行一系列的关键字比较。这一类查找方法建立在“比较”的基础上,查找的效率与比较次数密切相关。理想的情况是能直接找到需要的记录,因此必须在记录的存储位置和它的关键字之间建立确定的对应关系,使每个关键字和结构中一个唯一的存储位置相对应。在查找时,只需根据这个对应关系找到给定值。这原创 2020-06-24 23:30:10 · 313 阅读 · 0 评论 -
OpenSSL之简介,安装及组成介绍
文章链接:https://codemouse.online/archives/2020-06-20185901OpenSSLOpenSSL是一个功能丰富且自包含的开源安全工具箱。它提供的主要功能有:SSL协议实现(包括SSLv2、SSLv3和TLSv1)、大量软算法(对称/非对称/摘要)、大数运算、非对称算法密钥生成、ASN.1编解码库、证书请求(PKCS10)编解码、数字证书编解码、CRL编解码、OCSP协议、数字证书验证、PKCS7标准实现和PKCS12个人数字证书格式实现等功能。OpenSSL采原创 2020-06-24 23:29:31 · 379 阅读 · 0 评论 -
XML从入门到放弃
文章链接:https://codemouse.online/archives/2020-06-16XML 简介目的使用 XML 标记语言可以做到数据或数据结构在任何编程语言环境下的共享。例如 我们在某个计算机平台上用某种编程语言编写了一些数据或数据结构,然后用 XML 标 记语言进行处理,那样的话,其他人就可以在其他的计算机平台上来访问这些数据或数 据结构,甚至可以用其他的编程语言来操作这些数据或数据结构了。这就是 XML 标记 语言作为一种数据交换语言存在的价值。XML和HTML的区别XML 和原创 2020-06-24 23:28:49 · 192 阅读 · 0 评论 -
Json从入门到放弃
文章链接:https://codemouse.online/archives/2020-06-16-22-08-11Json 语法范例:{ "name": "milo", "age": 80, "professional": { "english": 4, "putonghua": 2, "computer": 3, }, "languages": ["C++", "C"], "phone"原创 2020-06-24 23:28:18 · 264 阅读 · 0 评论