自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

imred的专栏

眼下你打算怎么办?

  • 博客(113)
  • 论坛 (1)
  • 收藏
  • 关注

原创 蹭个热点:用bash统计csdn博客阅读量是否符合本福特定律

拜大洋彼岸国家大选所赐,本福特定律这两天在微博和知乎上突然火了起来,因为有人根据本福特定律推断大选投票结果有人为操纵的痕迹。那么什么是本福特定律呢?本福特定律的内容大致是这样的:对于一组样本足够大,且难以人为操控的自然十进制数据,如世界上所有国家的人口、面积、GDP等,其首位为n的数据占数据总量的比例为:P(n)=log⁡10(n+1n)P(n)=\log_{10}\left(\frac{n+1}{n}\right)P(n)=log10​(nn+1​)计算下来,以1打头的数据占数据总量的30.10%

2020-11-09 22:07:23 154 2

原创 使用OpenGL实现ASCII Art滤镜

效果图:仓库地址:https://github.com/im-red/asciiart_gl之前使用Qt实现过一个CPU版本的ASCII Art滤镜,流程大致如下:根据字体选择确定单元方格大小。将每个可用字符绘制到单元方格大小的空白图片上,计算每个可用字符的平均灰度值。根据第二步计算出来的每个可用字符的平均灰度值,生成一个0~255灰度值到字符的映射表。按单元方格大小对输入图片进行划分,灰度化后求每个方格的平均灰度值。查询灰度值到字符的映射表,对输入图片的每个方格使用字符进行填充。CP

2020-10-25 16:47:27 69

原创 Qt:监控一个QObject对象发射的所有信号

如果我们想要监控一个QObject对象发射的所有信号,同时又不追求手段的通用性的话,可以给目标对象的每个信号写一个槽函数,然后手动connect。这听起来就麻烦,有没有不那么麻烦的通用方法呢,自然是有的。如果能对Qt的信号槽原理进行一点深入的探索,我们就能以很简单的方法达到我们的目的。以下代码均基于Qt5.12.7。信号槽的连接保存在sender的metaObject中,其数据结构为QObjectPrivate::Connection:struct Connection{ QObject *

2020-10-08 18:08:12 192

原创 为什么std::priority_queue有一个构造函数接受Compare类型对象作为参数?

在我之前写的一篇博客《使用decltype取函数类型遇到的“invalidly declared function type”问题》中,最近收到一条评论:X: 想问问,既然模板里面已经传入了comp指针了,为什么构造函数里还要再传一次呢?我先把情境描述的更清楚一些,std::priority_queue是优先队列的标准库实现,其声明如下:template< class T, class Container = std::vector<T&g

2020-09-08 21:51:35 88

原创 localhost还是127.0.0.1,这是一个问题(并不是)

(本文内容仅针对Linux环境,内核版本4.15,thrift版本0.11.0,glibc版本2.27)localhost比127.0.0.1快?有江湖传言称,“使用localhost访问本机服务比使用127.0.0.1要快”,这有没有道理呢?自然是没有道理的,除了个别的特例(如https://www.php.net/mysql_connect)因为会对localhost做特殊处理(使用UNIX domain socket替代TCP socket)所以可能快一点(存疑,未验证)外,其他情况使用loca

2020-07-29 22:59:27 202

原创 Linux:利用内核日志记录系统启动时产生的进程树
原力计划

前言之前项目中遇到过一个bug,bug产生的原因是某个程序在两个不同的启动脚本中被同时启动了两次,系统中出现了两个实例。这个程序在代码内部没有保证单实例,靠shell脚本的pidof(1)命令保证单实例,然而因为两个启动脚本的启动时间太过接近,pidof(1)没能起作用,导致程序被启动了两次。出了这个bug后就想着需要梳理一下系统在启动时都运行了哪些脚本,这个系统“传承”了估计有七八年,启动脚...

2020-04-12 16:07:39 177

原创 四种迷宫生成算法的实现和可视化
原力计划

(上图是使用随机化Prim算法生成一个200x200的迷宫的过程)Github项目地址:maze前言本文中的迷宫指的是最常见的那种迷宫:迷宫整体轮廓是二维矩形,迷宫里的格子是正方形的,格子上下左右各相邻另外一个格子(边和角除外),迷宫内部没有环路,也没有无法到达的格子,起点在一个角(本文中为左上角),终点在另一个角(本文中为右下角),从起点到终点有且仅有一条路径:每个格子都可以抽象成图...

2020-04-05 17:29:24 601

原创 使用bash和graphviz分析并可视化C/C++源文件依赖关系

流程流程并不复杂:使用find命令搜索指定目录所有C/C++源文件扫描所有源文件,使用cpp(The C Preprocessor)过滤掉注释后,使用sed提取#include,生成依赖条目将所有依赖条目拼成.dot文件,然后使用graphviz中的dot工具将.dot文件转为.png图片代码代码的Github仓库为dep,为了方便~~(以及凑字数)~~放在这里一份:#!/bin...

2020-03-29 17:34:28 173

原创 clang:FunctionDecl::isOutOfLine()和FunctionDecl::isInlined()能同时返回true吗?
原力计划

最近读clang源码时发现这么一段代码:FunctionDecl *FD = ............if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) { ...... if (MD->isOutOfLine() && ......) { ...... if (FD...

2020-03-16 00:32:46 232

原创 Qt:为什么QGraphicsView设置Antialiasing/SmoothPixmapTransform没生效?

QGraphicsView::setRenderHint有两个常用的选项:QPainter::Antialiasing和QPainter::SmoothPixmapTransform,前者是用来打开反走样功能,后者用来在对图片进行缩放时启用线性插值算法而不是最邻近算法。然而这两个选项都有一些坑,想达到预期的效果的话得做一些额外的功课。QPainter::Antialiasing和QOpenGLW...

2020-03-08 00:37:00 629

原创 bash的几种特别的I/O重定向语法

下面这几种重定向语法都很简单,容易记住:ls > stdout.tx # 用标准输出覆盖stdout.txtls not-exist-file 2> stderr.txt # 用标准错误覆盖stderr.txtls exist-file not-exist-file > stdout.txt 2> stderr.txt # 用标准输出覆...

2020-02-22 14:41:23 117

原创 当std::bind遇到非静态类成员函数

之前看项目代码在实现表驱动方法时,经常会遇到这样的代码:// enum { ID0, ID1, ID2 };// std::map<int, std::function<void()>> Foo::m;// void Foo::func0(){}// void Foo::func1(){}// void Foo::func2(){}void Foo::init...

2020-02-11 21:32:53 580

原创 QString和QByteArray

QString有一个未标记为explicit的构造函数QString(const QByteArray &ba),导致许多形参为QString的函数可以接受类型为QByteArray的实参,时间久了会会以为这两个类可以随意混用,但实际并不是这样,这两个类适用的场景还是有区别的。QString相较QByteArray更高级更抽象,QByteArray则更底层更具体。QString基本单位是...

2020-02-10 23:45:34 90

原创 Linux C/C++调试之五:程序运行耗时的组成

分析程序出现的启动缓慢、响应缓慢和操作卡顿等性能问题时,第一步不该是打开代码编辑器浏览我们的代码,而是首先确定问题是否发生在我们的代码中,简单点的方法就是打开top做一个大致的判断,看一看各CPU的us、sy、id耗时的占比都是多少。进一步来讲,我们需要确定时间都花到什么地方了,是我们的代码中?内核中?还是进程睡大觉的地方?现在假设我们的程序运行在一个CPU资源丰富的环境中,因此就不考虑进程争夺C...

2020-01-11 23:00:24 256

原创 条件变量为什么要和互斥量一起使用?

一个简单的使用条件变量的场景:主线程从stdin读取一个字符串,然后由echo线程打印这个字符串,正确的代码是这样的:#include <iostream>#include <condition_variable>#include <mutex>#include <thread>#include <string>#includ...

2020-01-02 21:56:01 497

原创 Linux C/C++调试之四:callgrind的局限

在上篇文章中我介绍了callgrind的大致用法,可以看出来,callgrind是一个非侵入式的,使用起来也很傻瓜的调优工具。初用时感觉这个工具非常趁手,是个程序都想用callgrind去分析一下。但深入使用后发现,callgrind不是银弹,它还是有一些缺陷的。这些缺陷的根源在于:callgrind使用指令数来衡量性能,而程序员用耗时来衡量性能,指令数与耗时仅仅是一个正相关的关系,而非成比例的关...

2019-09-01 23:49:51 354

原创 Linux C/C++调试之三:性能分析工具callgrind的使用

callgrind是valgrind工具套件中用于分析程序性能的一个工具,它能够得到粒度为函数、代码行和指令级别的性能数据,具体来说,我们可以得到某个函数、某行代码、某条指令处累计执行了多少条指令。我们看一个实例:// foo.cppint accumulate(int begin, int end){ int result = 0; for (int i = begin;...

2019-09-01 21:13:55 615

原创 使用googletest测试可能断言或导致进程退出的函数

做单元测试,一般是验证函数输出数据与预期是否相符。但是也有例外,我们可能需要验证函数在接收到非法参数时是否会断言或抛异常,例如下面这个例子:int foo(int *p){ assert(p != nullptr); return *p;}当传给foo的实参为nullptr时,运行的预期结果就是断言后进程异常退出。这在单元测试中如何验证呢?如何不让这些验证异常值的用例干扰...

2019-08-26 23:41:56 506

原创 gettimeofday和clock_gettime是不是系统调用?

在《Linux多线程服务端编程》一书5.1节中提到过,在x86-64的Linux上,gettimeofday不是系统调用,不会陷入内核。其实这种说法有点小问题,因为gettimeofday确实是个系统调用,但是linux的vdso(virtual dynamic shared object)机制帮我们做到了在调用这些系统调用时不陷入内核,从而提高了性能。vdso机制说白了就是在用户空间帮我们实现...

2019-08-25 16:13:07 2542

原创 Qt使用OpenGL进行多线程离屏渲染

基于Qt Widgets的Qt程序,控件的刷新默认情况下都是在UI线程中依次进行的,换言之,各个控件的QWidget::paintEvent方法会在UI线程中串行地被调用。如果某个控件的paintEvent非常耗时(等待数据时间+CPU处理时间+GPU渲染时间),会导致刷新帧率下降,界面的响应速度变慢。假如这个paintEvent耗时的控件没有使用OpenGL渲染,完全使用CPU渲染。这种情况处...

2019-07-28 11:58:14 4911 12

原创 linux下监控shell脚本或可执行程序启动过的子进程

使用history命令可以查看在shell中直接执行过的命令,但是无法查看间接执行过的命令,或者说启动过的子进程。举个例子,shell脚本或者make命令都会启动一些子进程,这些子进程并不会显示在history命令的输出中,那么如何监控他们启动过哪些子进程呢?首先需要明确的是,shell脚本靠得也是sh可执行程序加载执行,./foo.sh的效果一般等同于sh ./foo.sh,因此监控shell...

2019-07-21 11:34:42 489

原创 利用libclang提取C++中enum值与名的映射

之前的一篇文章中,有思考过如何将enum的值与名进行映射,其中一种方法是利用工具进行预处理生成。最近由于项目中有类似的需求,所以学习了libclang,写了一个小工具实现映射。整体流程非常简单:匹配enum声明的AST节点。获取enum声明AST节点的类型(即枚举类名前面附上作用域)获取enum声明所在文件名(用于过滤系统头文件中的枚举)获取enum声明所在文件行号(可用于区分同一命名...

2019-06-04 23:57:16 644

原创 ptrace系统调用的实现

最近遇到这样一个问题,机器跑着跑着画面冻结了,打开top看到Xorg的cpu占用率100%。想用gdb挂上去看一下,结果gdb一直卡着挂不上去。后来又换用perf分析,结果发现进程99%的时间花在了一个ioctl调用。这个ioctl操作的是nvidia显卡,进程实际上是卡在了nvidia的驱动中。我对gdb挂不上去这件事感到很好奇,之前除了因为进程已经被另一个gdb调试而导致gdb挂不上去之外,...

2019-05-12 15:32:28 1218

原创 Qt在Linux下如何查找可用字体

最近遇到一个问题:一个Qt程序在Windows上正常运行,在Linux下编译运行后汉字就全变成方块了,成了名副其实的“方块字”。我一开始考虑是字符编码问题,调用QChar::unicode检查中文字符的编码,发现没有问题。如果不是编码问题,那就需要考虑是字体问题了。然后就安装了文泉驿字体,然后将控件字体设置为文泉驿,发现还是没有用。调用QFontDatabase::families检查所有可...

2019-04-09 20:58:13 1545

原创 C++11中静态局部变量初始化的线程安全性

前言大家都知道,在C++11标准中,要求局部静态变量初始化具有线程安全性,所以我们可以很容易实现一个线程安全的单例类:class Foo{public: static Foo *getInstance() { static Foo s_instance; return &s_instance; }private: F...

2019-04-07 15:03:31 4184 2

原创 Myer差分算法(Myer's diff algorithm)

Myer差分算法是一个时间复杂度为O(ND)的diff算法,就以diff两个字符串为例,其中N为两个字符串长度之和,D为两个字符串的差异部分的总长度。这个算法首先发表在An O(ND) Difference Algorithm and Its Variations。Myer差分算法直接解决的问题是最长公共子序列(LCS)的等价问题——最小编辑脚本(SES)问题。当然了,这是论文中的表述,在我看来...

2019-04-03 21:51:41 1657

原创 编辑距离算法和Levenshtein距离算法

前言最近在研究diff工具的实现,已经写了一个简单的demo,不过目前这个demo只是把Levenshtein距离算法的结果用Qt可视化了出来而已,还没有实用价值,界面如下:各种diff工具的核心基本都是编辑距离算法,网上许多文章把编辑距离算法等同于Levenshtein距离算法,但实际上Levenshtein距离算法只是各种编辑距离算法其中之一。各种编辑距离算法会使用不同的编辑操作种类,例...

2019-03-25 20:53:47 1384

原创 C++:shared_ptr的隐式转换

最近遇到这样一个编译问题,代码是这样的:#include <memory>#include <iostream>class Base{public: virtual ~Base() {}};class Derived : public Base{public: ~Derived() {}};void processSpBase(s...

2019-03-22 00:04:03 1877

原创 Linux C/C++调试之二:使用strace追踪程序系统调用

在之前的一篇文章中,我介绍了一种调试手段:利用LD_PRELOAD机制,拦截动态链接器对动态库的符号解析,达到监控程序IO的目的。事实证明我还是太naive了,我们大可利用现成的工具——strace,来更好地完成这一项工作。strace不只能跟踪程序IO,它能跟踪程序的所有系统调用,实现的基本手段是ptrace系统调用,不过实现细节还没研究过,今天只总结一下它的用法。首先用strace来跟踪一...

2019-03-02 18:27:42 976

原创 C++的返回值优化(RVO,Return Value Optimization)

前言大家都知道“过早的优化是万恶之源”这句话,然而我相信其中的大多数人都不知道自己是不是在做过早的优化。我也无法准确的定义什么叫做“过早的优化”,但我相信这“过早的优化”要么是得不偿失的,要么干脆是有害无利的。今天我就想举个我认为是“过早的优化”的例子。从函数返回值为了从一个函数得到运行结果,常规的途径有两个:通过返回值和通过传入函数的引用或指针(当然还可以通过全局变量或成员变量,但我觉得这...

2018-12-31 22:51:28 2006 2

原创 一次尝试使用cmu sphinx做语音识别的失败记录

好好的C++不去写,为啥想起来搞什么语音识别?事情是这样的,我经常躺在床上听歌,使用电脑连音响播放,因为我比较懒,切歌啥的都直接召唤小娜帮我做,可以节省体力。然而小娜笨啊,除了能切歌啥也干不了,我要是听到一首好听的,还得爬起来去收藏,这多么麻烦是不是?小娜也没开放啥接口可以自定义命令,就想自己写一个程序,识别到我的指令后,按照播放器的快捷键虚拟键盘按键事件。网上一搜“开源语音识别引擎”,好,就是...

2018-12-24 00:20:57 1870 1

原创 QML:使用Model/View框架时根据不同的数据项使用不同的delegate

Qt自带的QML使用Model/View框架的example中,展示数据使用的delegate(似乎)都是唯一的,不能根据不同的Model数据项使用不同的Item来展示。如果有这样一个需求:Model的数据项中有一个字段为itemType,展示数据时希望能够根据这个字段使用不同的Item来展示数据,能否实现呢?自然是可以的:我们可以将View的delegate字段设为一个Loader,然后让这个L...

2018-12-16 17:42:32 631

原创 QML:使用ListView运行时动态载入Item

想要实现使用ListView运行时动态载入Item,需要两个步骤:动态生成Item将动态生成的Item插入到ListView的model中对于这两个步骤,前者可以使用createComponent和Component.createObject实现,后者可以使用ObjectModel实现,详细内容可见官方文档:http://doc.qt.io/qt-5.9/qml-qtqml-qt.ht...

2018-12-16 16:56:14 3755 2

原创 linux下鼠标事件丢失与evdev缓冲区溢出问题

之前遇到这样一个bug:在一个性能较差的linux平台上的一个Qt程序,当UI线程在执行耗时操作时,界面会卡顿,而这时频繁点击滑动鼠标,会出现鼠标事件丢失的问题。举个例子:某个控件收到一个鼠标按下的事件,但再也没有收到鼠标弹起事件,而此时鼠标按键实际上已经弹起了,这就导致程序进入了一种异常状态,除非再次点击鼠标,否则无法恢复。上面这个问题是在QApplication的事件过滤器中确定的,全局的QA...

2018-12-15 17:33:18 402

原创 在Linux下实现一个使用键盘控制的虚拟鼠标

在Linux下创建一个虚拟鼠标设备还是比较简单的,使用内核uinput模块提供的函数即可。创建出虚拟鼠标以后,在主线程监听键盘的事件,当特定的键(此处使用了小键盘的数字键8、2、4、6)被按下或弹起后,进行记录。在另一个线程根据主线程记录的flag创建输入事件,然后将输入事件写入虚拟鼠标设备即可。在实现程序时一个让我思考时间比较长的问题是:是否需要另外创建一个线程来写虚拟鼠标设备。当一个键被按下...

2018-11-11 21:48:24 2187 1

原创 cmake构建C++项目避免编译时对第三方库头文件进行依赖检查

最近有同事反应一个使用cmake构建的C++项目编译很慢,具体表现是随便修改一个很简单的cpp源文件后,重新编译生成可执行文件的时间需要用3分钟左右。统计了一下整个增量编译过程各阶段耗时,发现时间主要消耗在了cmake生成依赖规则和make检查依赖规则上。生成的依赖规则文件depend.make有200M左右,包含依赖规则条目有100W行以上。所以生成依赖规则和检查依赖都会消耗大量时间。进一步分析...

2018-11-06 00:09:46 3589

原创 计算二分图(bipartite graph)交叉点(crossing)的数量

对于一个二分图,如果图的两个部分的顶点都按照顺序分别排列在一对平行线上,如下图,如何计算这个二分图的边有多少个交叉点呢?需要注意两点:1. 在图的顶点处连接的边不认为产生了交叉点,如下图在c、d、B和D点连接的边;2. 如果交叉点有两条以上边经过,这些边中的每对边都要算作产生了一个交叉点,如下图Bd、Cc和Db算作产生了3个交叉点。那么这个图共有多少个交叉点呢?数一数就可以得出结论,答案是5个...

2018-09-28 00:24:56 1887

原创 Linux下对input设备调用ioctl时指定EVIOCGBIT选项时的缓冲区该多大

我们有时候需要获取/dev/input目录下的eventX设备支持哪些事件(EV_KEY、EV_REL和EV_ABS等),可以通过ioctl调用指定EVIOCGBIT(ev, len)选项来获取,例如:ioctl(fd, EVIOCGBIT(0, EV_MAX), buf);来获取fd设备支持的事件。这涉及到一个问题:buf需要指定多大的长度? EVIOCGBIT宏的第二个参数是事件标志...

2018-09-12 22:57:26 1494 2

原创 gdb的watchpoint在系统调用中被修改似乎不会被触发

今天遇到一个越界写问题,覆盖了栈底的金丝雀值,导致运行时报“*** stack smashing detected ***”。一开始尝试用gdb的watchpoint定位,但就是眼睁睁的看着运行结束后金丝雀值被修改而没有触发watchpoint,最后无奈一行行的定位,发现是一个ioctl导致的越界写。 后来我试着研究watchpoint未被触发的原因,在GDB的官方Wiki发现这么一句话:...

2018-09-09 22:54:39 733

原创 Qt的事件驱动机制与eventfd

简介Qt是一个事件驱动的GUI框架,那么,这个“事件驱动”说的是什么呢?以我的理解就是:对于UI线程,除了初始化代码和主循环本身之外,跑在CPU上的每条指令,要么是为了接收事件,要么就是某个事件触发的,这个事件可以直接来源于用户操作,也可以间接来源于用户操作(处理用户操作事件时触发了需要异步处理的其他事件),或者来源于socket,或者来源于定时器,等等。使用事件驱动能够避免对CPU时间的...

2018-09-02 20:45:36 1319

空空如也

CSDN博客首页文章没人维护了么?

发表于 2019-03-25 最后回复 2019-03-26

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人 TA的粉丝

提示
确定要删除当前文章?
取消 删除