cpp
文章平均质量分 71
guotianqing
这个作者很懒,什么都没留下…
展开
-
c++矩阵计算性能对比:Eigen和GPU
生成随机矩阵有多种方式,直接了当的方式是使用显式循环的方式为矩阵的每个元素赋随机值。另一种方式是使用Eigen库,它提供了矩阵运算的库。原创 2022-07-15 18:44:38 · 3530 阅读 · 1 评论 -
获取字符串的md5sum值——分别使用shell、python、c++实现
md5sum在Linux下,我们经常使用md5sum命令来查看两个文件是否相同。md5sum命令会逐位对文件的内容进行校验。是文件的内容,与文件名无关,也就是文件内容相同,其md5值相同。存在两个文件不同,但md5sum相同的情况。不过这个情况出现的概率还是很低的,所以md5值仍然是常用的方法。md5值是一个128位的二进制数据,转换成16进制则是32(128/4)位的进制值。如果对结果的准确性要求极高,可以使用sha系列算法,比如SHA1、SHA256、SHA384、SHA512等。如前所述原创 2022-05-07 15:08:19 · 5993 阅读 · 0 评论 -
C++中几个问题的思考
死锁及避免死锁的产生:线程a获得资源x的锁后,去获取资源y的锁,在这个空当,线程b获得了资源y的锁,再去获取x的锁。此时,显然地,a获取y的时候,陷入等待,b获取x的时候,也陷入等待,两个线程因为锁而死亡,即发生了死锁。在实际的项目中,死锁是一种较难发现和定位的程序bug,因为程序表面上看起来一切正常,没有崩溃,不会有coredump。但程序此时的两个线程已经没有在工作了,它们的既定任务也不会被正确地执行,所以无法得到正确的结果。死锁的定位:如果在程序中使用了多个锁,特别是使用了嵌套锁,而线程又原创 2022-03-20 17:59:34 · 1078 阅读 · 0 评论 -
c++ nvcc编译CUDA程序入门示例
nvccnvcc是NVIDIA CUDA Compiler,用来编译host和device程序。这里的术语:host:指CPU及其内存device:指GPU及其内存使用nvcc,就可以编译CUDA程序,CUDA程序包括host代码和device代码。在安装CUDA Toolkit后,nvcc内含其中。注意要安装与显卡版本匹配的CUDA Toolkit。我的nvcc版本:% nvcc --versionnvcc: NVIDIA (R) Cuda compiler driverCop原创 2022-02-28 18:49:43 · 6063 阅读 · 1 评论 -
c++中set和unordered_set的区别
作用set与unordered_set一样,都是关联式容器,和 map 容器不同,使用 set 容器存储的各个键值对,要求键 key 和值 value 必须相等。当使用 set 容器存储键值对时,只需要为其提供各键值对中的 value 值(也就是 key 的值)即可。使用 set 容器存储的各个元素的值必须各不相同。从语法上讲 set 容器并没有强制对存储元素的类型做 const 修饰,即 set 容器中存储的元素的值是可以修改的。但是,C++ 标准为了防止用户修改容器中元素的值,对所有可能会实现原创 2021-11-29 19:07:03 · 2149 阅读 · 0 评论 -
unordered_map多线程崩溃在find
崩溃最近程序中出现了崩溃现象,经过查询,发现是崩溃在STL容器的查询中。崩溃的截图如下:关于unordered_map无序 map 容器,unordered_map 容器不会像 map 容器那样对存储的数据进行排序。unordered_map 容器底层采用的是哈希表存储结构,该结构本身不具有对数据的排序功能,所以此容器内部不会自行对存储的键值对进行排序。关联容器删除一个元素的时候,当前的迭代器会失效,其他的迭代器不会失效,增加一个元素的时候,迭代器不会失效。线程安全性的保证:多线程同原创 2021-09-23 18:16:59 · 6019 阅读 · 1 评论 -
数值在容器中的分位数
背景存在一个数据序列,且持续有新的数据到来,需要知道当前到来的数据在原数据序列的分位数。假设数据是double类型,序列存储在vector中。实现方案有多种方式可以实现该功能。暴力法最直观的方式是使用暴力法解决。对vector排序,然后遍历整个容器,找到给定值的index,得到index/vector.size即为分位数。代码如下:void GetQuantileForLoop(const vector<double>& ori, const double val)原创 2021-07-06 18:47:17 · 289 阅读 · 0 评论 -
c++11中emplace_back vs push_back
引言在C11中,有两种方法可以把元素放入容器中:emplace_back和push_back。push_back是C11之前就有的,而emplace_back是C11中新加的。既然它们的作用都是一样的,那么为什么C11中又加入了一个emplace_back?既生瑜,何生亮?在实际的项目编码中,到底用哪个呢?优先选用emplace_back考虑下面这段非常常见的代码:std::vector<string> vs;vs.push_back("xyz");其中,vs容器持有原创 2021-05-16 21:18:39 · 841 阅读 · 0 评论 -
浅谈std::thread的可联结性
联结性对于std::thread创建的线程对象,要么join它,要么detach它,否则会导致程序崩溃。要想从理论上解释上述原因,就要了解一下thread的可联结性。std::thread对象都是处于两种状态之一:可联结的和不可联结的。可联结状态:std::thread对应底层以异步方式已运行或可运行的线程对应的底层线程处于阻塞或等待调度对应的底层线程已运行至结束不可联结状态:默认构造的std::thread:它没有可以执行的函数,因此没有对应的底层执行线程已移动的std::th原创 2021-05-09 15:25:06 · 492 阅读 · 0 评论 -
使用std::async代替std::thread启动异步任务
std::threadc++11在语言层面对并发编程提供了有力的支持,std::thread就是一例,它以线程的方式启动异步任务。关于thread创建线程对象并使用的用法,请参考 std::thread创建线程的几种方式使用thread对象,并在其上运行一个函数,这是基于线程的程序设计:int DoAsyncWork();std::thread t(DoAsyncWork);std::async还有一种更好的方式:基于任务的程序设计。即把任务函数传递给std::async,示例:aut原创 2021-05-09 14:06:53 · 1835 阅读 · 0 评论 -
C++11中的万能引用和右值引用使用注意事项
简介右值引用仅会绑定到右值,主要用于识别出可移对象。可以绑定到左值、右值、const、非const、volatile、非volatile等等一切对象的引用,称为万能引用。右值引用和万能引用都使用形如“T&&”的符号表示。下面做个小测试,试着区分一下下面的引用属于万能引用还是右值引用:// 1.void f(Foo&& p);// 2.Foo&& var1 = Foo();// 3.auto&& var2 = var1;原创 2021-04-25 13:21:30 · 753 阅读 · 1 评论 -
浅谈C++11中的move和forward
含义move和forward都是C++11中引入的,它们是移动语义和完美转发实现的基石。move:不能移动任何东西,它唯一的功能是将一个左值强制转化为右值引用,继而可以通过右值引用使用该值,以用于移动语义从实现上讲,std::move基本等同于一个类型转换:static_cast<T&&>(lvalue)forward: 不转发任何东西,也是执行左值到右值的强制类型转换,只是仅在特定条件满足时才执行该转换典型使用场景:某个函数模板取用了万能引用类型为形参,随原创 2021-04-18 18:18:54 · 2484 阅读 · 0 评论 -
c++ vector的reserve到底对性能影响几何?
几个属性关于vector,有以下几个与Capacity相关的属性需要了解:size: 实际大小,即实际含有几个元素max_size:最大能容纳的元素个数,取决于操作系统和编译器,一般不会变化resize:改变实际大小到指定值,没有设置值的位置使用默认值填充capacity:容量,当前已经分配的内存能够容纳的元素个数,该值大于等于sizeempty:是否为空,同 size == 0?,若为空则返回true,否则falsereserve:预先设定容量到指定值,背后执行的可能是内存分配shri原创 2021-04-15 08:32:11 · 1869 阅读 · 0 评论 -
C++获取随机数的3种方式
简介随机数的使用越来越广泛。除了加密领域,在日常生活中也随处可见。如抽签、抽奖、测试等。这里描述一个与Redis使用有关的场景:Redis过期时间的设置。即建议对大批量的数据过期时间,设置一个值,并加上一个随机值,防止批量数据同时失效,造成缓存雪崩或影响性能。c++11 c++11引入了头文件,用于生成随机数。它包括两个部分:random engine: 生成随机的bit流distribution: 生成满足用户需求的随机数用法如下:使用seed初始化random engine原创 2021-04-03 10:25:42 · 15054 阅读 · 0 评论 -
std::thread创建线程的几种方式
简介自从c++11开始,使用std::thread类创建线程是非常方便的。类thread关联的对象构造后立即执行(当然会有操作系统调试延迟)作为构造函数参数的函数的返回值将被忽略如果函数通过抛出异常终止,则调用std::terminate但函数可通过std::promise或通过修改共享变量(可能需要同步,请参见std::mutex和std::atomic)将其返回值或异常传达给调用方注意以下几点:线程对象是不可复制的,只能移动线程对象要么被join,要么detach,否则可能会导致原创 2021-03-19 18:48:14 · 2360 阅读 · 0 评论 -
Linux下C++跨平台获取高精度时间戳
简介C++语言本身及Linux操作系统均提供了时钟相关的函数,可以方便获取时间。但是,在一些场合下,需要的时间精度不同,又不能通用。如果依赖于Linux平台,又不能做到跨平台。所以优化考虑使用C++语言本身提供的函数。本文介绍使用 std::chrono 命名空间下的函数来获取时间戳。需要 c++11 支持。关于时间函数的介绍,请参考 Linux c++获取本地毫秒级精确时间 。获取时间跨度在测试一段程序的耗时时,经常需要统计时间跨度。示例代码如下:int countTimeCons原创 2021-02-10 14:27:58 · 2339 阅读 · 0 评论 -
Eigen——c++矩阵库使用入门实践
简介一句话介绍Eigen:Eigen is a C++ template library for linear algebra: matrices, vectors, numerical solvers, and related algorithms.Eigen是用于线性代数的C++模板库:用于矩阵,向量,数值求解器和相关算法运算。特点:功能完善:支持所有大小的矩阵、支持所有标准数据类型等速度极快:表达式模板允许在适当的情况下智能地删除临时文件并启用延迟计算高可靠性高灵活性机器学原创 2020-12-21 19:15:27 · 4113 阅读 · 0 评论 -
c++ google编程风格
简介编码不易,每家公司都有它的脾气。c++的编码风格也有不少流派,这里独选google,一是因为它牛逼,向牛逼的学习总没错,二是它有很多开源项目使用的就是这个风格。当你不知道怎么做才好时,就先用google的吧,已经有无数前仁验证过了。本文不是要再罗列一遍所有的细则,而是提炼出编码中随时需要使用的部分,作出总结,这样方便参考。具体结节,还请稳步开源文档:C++ 风格指南。头文件使用 #define 保护,为保证唯一性,头文件的命名使用项目目录的全路径避免使用前置声明,使用 #inclu原创 2020-12-10 18:57:56 · 1128 阅读 · 0 评论 -
c++中字符串转浮点数stod vs atof
背景程序需要从文件中读取double精度的数据。随着程序的更新,文件也会更新。但有时候,更新了文件,却忘记更新程序,这时启动程序时,就会coredump。gdb coredump也很容易看出问题,但不能一出问题就让程序crash啊。于是加了try来catch异常,但是无果,还是dump,于是查了一下,发现了atof的问题。stod vs atofatof是c代码里的库函数,用于把字符串转换为double精度的数字,原型如下:#include <stdlib.h>double原创 2020-11-26 20:59:38 · 9409 阅读 · 0 评论 -
c++创建目录的几种方式
system调用这种方法简单粗野,适用于Linux系统。代码如下:#include <iostream>#include <string>#include <sys/types.h>#include <sys/stat.h>#include <signal.h>#include <errno.h>int main(int argc, char **argv){ if (argc != 2) { cout原创 2020-11-19 19:56:14 · 22758 阅读 · 2 评论 -
c++跨平台工具库
简介使用c++开发程序时,虽然c11和boost提供一些跨平台的特性支持,但是涉及到操作系统层面的一些功能还是不能有效地跨平台。本文旨在提炼出这些经常使用的,但又不能跨平台的功能,形成一个工具库,方便以后使用。代码结构该工具库共由两个文件组成: cross_platform_utils.h和cross_platform_utils.cpp。h文件如下:#ifndef _CROSS_PLATFORM_UTILS_#define _CROSS_PLATFORM_UTILS_#include原创 2020-11-14 15:52:34 · 913 阅读 · 0 评论 -
boost thread类创建和销毁线程示例
boost threadboost thread类使用简单,能够方便地管理整个线程的全生命周期,应用广泛。thread配合ios使用时,能够方便地创建线程池,具体请参考boost::asio::io_service创建线程池简单实例。创建线程对于一般的使用,是启动一个线程,运行一个函数,在函数内完成特定的任务。#include <boost/thread.hpp>void foo(){ cout << "foo" << endl;}boost:原创 2020-11-02 19:16:23 · 2788 阅读 · 0 评论 -
c++忽略大小写的字符串比较方法
目的实现如下功能:std::string str1 = "iloveyou";std::string str2 = "ILoveYou";if (icasecompare(str1, str2)) { cout << "str1 is equal to str2\n";}bool icasecompare(const string& s1, const string& s2){ //?}使用系统库这是比较简单的方法,但由于不是c++标准的一原创 2020-10-27 19:16:15 · 16460 阅读 · 0 评论 -
c++ map取值的find、[]、at方法特性对比
背景项目中经常需要对std::map进行插入和取值操作,以前经常使用find和[]直接操作,c++11引入了at方法。本文主要介绍它们的使用方法和不同之处。find很直观的查找元素操作,如:#include <map>#include <iostream>using namespace std;int main(){ map<string, int> m; m["xiaoming"] = 80; m["xiaogang"] = 90; m原创 2020-10-01 17:20:30 · 31779 阅读 · 3 评论 -
获取map或set中的key到vector中的方法
简介有时需要对map中的key进行一些单独的处理,这时将它们拷贝到一个vector中再处理会方便些。以下方法对unordered_map同样适用。以key为string类型为例。先介绍几种获取map中key的方法,对于获取set中key的方法,与map类似。文末简要介绍。遍历取值这是普通朴素的方法,直接上代码:// 省略头文件和using声明template<typename T>void MapKeysToVector(const T& in, vector<原创 2020-09-16 18:40:20 · 4430 阅读 · 0 评论 -
c++协程初探
简介介绍协程之前,先来复习一下进程和线程。进程:应用程序的启动实例,是计算机资源分配的最小单位,进程拥有代码和打开的文件资源、数据资源、独立的内存空间。线程:从属于进程,是程序的实际执行者。是计算机调度和执行的最小单位。一个进程至少包含一个线程,为主线程,也可以有更多的子线程,子线程共享进程的文件和数据。线程拥有自己的栈空间。它们在操作系统中的关系如图:通常,应用程序是采用单进程多线程的方式,这样既能使用较小的系统资源,又能把占用的资源使用率最大化。多线程允许程序充分利用多核cpu的优势原创 2020-09-08 19:22:42 · 834 阅读 · 0 评论 -
c++使用shplib读取dbf实时数据
简介看这篇文章的朋友应该已经知道shplib了,官方介绍如下:The Shapefile C Library provides the ability to write simple C programs for reading, writing and updating (to a limited extent) ESRI Shapefiles, and the associated attribute file (.dbf).支持三类文件:XXX.shp - holds the actua原创 2020-07-10 19:08:00 · 1485 阅读 · 0 评论 -
c++文件流打开模式与is_open方法
检测流状态的方法在c++中经常需要读写文件,在打开文件进行操作之前,我们需要确保流的打开状态正常。可以通过以下方法判断流状态正常:#include <fstream>ifstream fin;fin.open("demo.txt");// 1st attemptif (fin.fail()) {} // open failed// 2nd attemptif (!fin) {} // open failed// 3rd attemptif (!fin.good()) {原创 2020-07-05 13:43:06 · 23738 阅读 · 2 评论 -
从两个排序算法实现c++策略模式
简介所谓策略,是指一系列的操作。比如古代打仗,可以直接双方对垒派兵厮打,也可以等到月明星稀偷营劫寨,还可以略施小计。这些都是策略。又比如计算税费时,不同国家的计算方法是不同的。如美国的10%,日本的8%,欧萌的12%…等,这些也都是策略。策略模式,就是把一个个的策略封装起来,并且使它们可以相互替换。以达到算法独立于客户的目的。这样可以在不改变客户的情况下灵活地变更各种策略(算法)。策略模式的目的就是为了适应不同的需求,把这些容易变化的点(不同策略之间可能会互换)封装起来。这样就能够在不变更原有代原创 2020-06-08 15:06:59 · 232 阅读 · 0 评论 -
从一个例子学习c++模板方法(Template Method)
示例需求:数据处理软件往往需要对表格内的每一条记录或者是一组特定的记录进行操作,执行步骤大概如下:遍历读表格,把需要处理的表格置入内存容器处理容器内的表格数据代码片断如下:// 第一个实现// 基类(模板类)class GenericTableAlgorithm{public: GenericTableAlgorithm(const string& table); virtual ~GenericTableAlgorithm(); // 负责所有工作: // a原创 2020-06-03 11:46:28 · 255 阅读 · 0 评论 -
c++私有继承与组合浅析
简介继承是面向对象编程的重要属性。有效地使用继承,可以复用现有的设计,加速产品开发进度。公有继承塑造了is-a关系,如苹果is a水果,所以苹果可以以public方式继承水果,所有被改写的成员函数满足“不要求更多,也不承诺更少”的原则。关于私有继承,它体现了is-implemented-in-terms-of关系,但这种关系又可以使用组合的方式来实现。那么,私有继承与组合之间到底是什么关系?什么时候应该使用私有继承?什么时候又应该尽量使用组合以替代晦涩的私有继承?本文作一探讨。从一个示例剖析原创 2020-05-20 11:41:43 · 508 阅读 · 0 评论 -
从一个示例反思如何避免c++中的临时对象
说明临时对象是隐晦的,但对性能的影响是不可忽视的。本文通过剖析示例,找出临时对象的藏身之所,曝光并消灭它。示例代码片断如下:string FindAddr(list<Employee> l, string name){ for (auto i = l.begin(); i != l.end(); i++) { if (*i == name) { ret...原创 2020-05-07 19:17:13 · 272 阅读 · 0 评论 -
c++11并发编程入门
简介并发能够充分利用多核心处理器,但并行编程却面临着严峻的挑战。并行编程的一个常见问题是数据同步,即多个语句同时访问同一资源,当一个线程在写,而另一个在读时,就会造成不可预料的后果。加锁可以在避免上述问题,但使用锁本身也带来了一系列问题,如死锁、效率低下等。不良的代码也可能造成cpu空转等待等资源浪费。在c++11之前,语言或标准库都没有对并发进行任何的支持。但c++11提供了以下支持:...原创 2020-05-07 19:16:15 · 570 阅读 · 0 评论 -
STL算法概览
非更易型算法这些算法不会改动元素值,也不会改变元素的次序。计数: count/count_if线性复杂度最大值最小值:max_element/min_element/minmax_element线性复杂度查找元素查找第一个匹配元素:find/find_if/find_if_not查找前n个连续匹配值:search_n查找第一个子区间:search查找最后...原创 2020-05-06 18:47:39 · 203 阅读 · 0 评论 -
c++ 常用STL容器使用简练总结
根据各容器的特点,作简练的总结。array带有STL容器接口的static c-style array大小固定,无法通过增加或移除元素改变它的大小,即size()总是返回同一值提供常量时间的随机访问功能,但只有at()会检查是否越界,其他调用若越界会导致未定义的行为对于基础类型,需要初始化:std::array<int, 4> a = {},否则初值不定使用data()...原创 2020-04-29 19:04:28 · 421 阅读 · 0 评论 -
c++判断vector中是否存在特定元素的方法
简介常常需要在vector中查找元素是否存在,或者确定元素的个数。但vector未提供相关的成员函数。这里不讨论手写for遍历的方法。无论从工作量还是效率方面,都应该优先选用STL算法。注意:对于任意的vector,查找某个元素需要耗费线性时间。除非该vector是有序的。算法模块提供了查找的多种方式。以下代码需要包含该头文件。以在vector中查找元素为例。方法与示例1. st...原创 2020-04-29 09:20:51 · 85263 阅读 · 7 评论 -
Effective STL读书笔记
没有c++程序不使用STL,这是一本讲述如何正确高效地使用STL的参考书。STL的核心是容器和算法,有了一定的使用经验之后,本书可以作为技术提升的点睛之笔。本书成文较早,技术已经发生了较大的变化,取其精华。容器慎重选择容器类型。标准STL序列容器:vector, string, deque, list。标准STL关联容器:set, multiset, map, multimap...原创 2020-04-10 20:58:36 · 334 阅读 · 0 评论 -
对多线程编程的一些思考
简述多线程编程在绝大多数服务端编程中不可避免,它以并发、高效、能够充分利用多核CPU被广泛使用。多线程编程的难度不是很大,只要能够注意好线程间资源的互斥,保证数据一致性,基本都能得到一个正确的多线程服务。然而,要想真正充分发挥出多线程编程的功效,却是需要技术、经验和一定的编程技巧的。可以说,有很多时候,考虑到保证数据一致性的额外编程开销,多线程服务的运行效率还不如单线程。本文结合笔者c...原创 2020-04-09 17:09:22 · 730 阅读 · 0 评论 -
Boost Asio异步TCP网络编程实例
简介本文主要描述TCP协议的实现,其他协议类似。关于Boost Asio库是什么,请参考Boost Asio快速入门。这篇文章概述了Asio库的重点。关于Boost Asio中提供的函数及使用,请参考Boost Asio 网络编程理论基础。该文可以快速预览,待到使用时再回来查询。另外,该文关于异步编程的关键注意点也有阐述。本文关注于异步编程的实现(关于同步和异步的异同,请参考上文)。异步...原创 2020-03-11 21:40:39 · 2800 阅读 · 2 评论 -
Boost Asio异步发送数据(async_write)崩溃问题记录
背景服务端与客户端之间的网络通信(使用Boost Asio库异步编程模式实现),客户端会向服务端请求数据。在刚开始的测试中,是没有出现问题的。后来有一次测试时,服务端查询完数据后,向客户端发送时总是崩溃。通过gdb调试,可以发现是在调用到异步发送函数(boost::asio::async_write)后崩溃的。打印的栈信息如下:Program terminated with signa...原创 2020-03-03 21:21:57 · 3916 阅读 · 0 评论