- 博客(41)
- 收藏
- 关注
原创 C++并发:并行算法函数
C++17向标准库加入了并行算法函数。他们是新引入的多个函数重载,比如std::find()、std::transform()和std::reduce(),其操作目标都是容器区间。相比各自对应的普通单线程版本,这些并行版本具有相同的函数签名,只是新增一个参数,用于设定执行策略。另外,并行执行方式会改变函数对复杂度的要求。因为并行算法需要处理的工作总量往往更多,才可以充分发挥系统算力。如果将一项任务分配到100个处理器上,但算法函数实现却另工作量变为原来的两倍,那么整体加速比只能达到50.
2025-03-03 08:35:57
804
原创 C++并发:高级线程管理
将可同时执行的任务都提交给线程池,再将其放入任务队列中等待,随后,任务队列中的任务分别由某一工作线程领取,执行完后,该线程再从队列中取出另一任务来执行,如此循环反复。线程池的构建设计好几项关键的设计议题:包括使用多少个线程为线程分配任务的最有效方法,以及等待任务完成与否等。
2025-03-03 07:12:18
131
原创 C++并发:设计无锁数据结构
算法和数据结构中,只要采用了互斥,条件变量或future进行同步操作,就称之为阻塞型算法和阻塞型数据结构。如果应用程序调用某些库函数,发起调用的线程便会暂停运行,即在函数的调用点阻塞,等到另一线程完成某项相关操作,阻塞才会解除,前者才会继续运行。这种库函数的调用被命名为阻塞型调用。
2025-02-01 21:41:46
897
原创 C++并发:设计基于锁的并发数据结构
(上一篇主要讲了底层逻辑,比较晦涩难懂,这一章讲解数据结构设计)对于并发场景,数据保护的形式主要如下:1 采用独立互斥和外部锁2 专门为并发访问自行设计的数据结构。
2025-01-30 11:51:42
1008
原创 C++并发:并发操作的同步
有时我们不仅要共享数据,也要让独立线程上的行为同步。例如,某线程只有先等待另一线程的任务完成,才可以执行自己的任务。C++提供了处理工具:条件变量和future并且进行了扩充:线程闩(latch),线程卡(barrier)
2025-01-05 20:57:32
836
原创 C++并发:在线程间共享数据
条件竞争:在并发编程中:操作由两个或多个线程负责,它们争先让线程执行各自的操作,而结果取决于它们执行的相对次序,这样的情况就是条件竞争。诱发恶性条件竞争的典型场景是,要完成一项操作,却需要改动两份或多份不同的数据,而它们只能用单独的指令改动,当其中的一份数据完成改动时,别的线程有可能不期而访。并且由于这样的场景出现的时间窗口小,因此一般很难复现场景定位。
2025-01-01 19:20:26
1074
原创 C++并发:线程管控
每个C++程序都含有至少一个线程,即运行main()的线程,它由C++运行时系统启动。随后程序可以发起更多线程,它们以别的函数作为入口。这些新线程连同起始线程并发运行。当main()返回时,程序就会退出;同样,当入口函数返回时,对应的线程随之终结。如果借std::thread对象管控线程,即可选择等他结束。
2024-12-28 09:04:14
434
原创 C++基础:内存分配
上述代码的动作分为两个方面:1 分配足够的内存,用来放置对象。2 调用一个constructor,为刚才分配到内存中的对象设定初值。
2024-12-20 07:27:54
427
原创 C++基础:操作符
以++为例可见后置操作额外生成了一个临时对象。并且为了避免形如i++++(即使合法,也只会累加一次。++++i和嘎合法),这样的写法,后置++为返回值加上了const,会导致i++++错误,来避免上述写法。
2024-12-18 23:06:17
340
原创 C++基础:标准库容器
2 从实践上说,置入函数在以下几个前提成立时,极有可能会运行得更快:1待添加的值是以构造而非赋值方式加入容器。"hadwkjs"是const char []类型对象,与std::string型别不匹配,先创建std::string临时对象temp。因此,如果欲添加值是以构造而非赋值方式加入容器,比如上面的情况,就用emplace_back.然后push_back返回,temp被析构,调用一次std::string的析构函数。1 从原理上说,置入函数应该有时比对应的插入函数高效,而且不应该有更低效的可能。
2024-12-15 22:03:01
324
原创 C++基础:并发
标准库中为期值准备了两个模板:std::future和std::shared_future。在很多情况下,他们的区别并不重要,所以经常仅仅谈论期值概念,意思是指对这两种都适用。
2024-12-13 09:01:05
532
原创 C++基础:智能指针
智能指针对裸指针进行了包装,他们的行为很类似被包装起来的裸指针,但是却避免了很多在使用裸指针时会遭遇的陷阱。C++11中总共有四种智能指针:std::auto_ptr是从C++98中残留下来的弃用特性,他是一种对于智能指针标准化的尝试,这种尝试后来成为了C++11中的std::unique_ptr。
2024-12-02 08:58:24
151
原创 C++基础:迭代器
模板使算法独立于存储的数据类型,迭代器使算法独立于使用的容器类型。输入迭代器必须能够访问容器中所有的值。这是通过支持++运算符来实现的。基于输入迭代器的任何算法都应当是单通行的(single-pass,可以递增,不能倒退)(不依赖前一次遍历时的迭代器值,也不依赖本次遍历中前面的迭代器值)程序的输出就是容器的输入。只能解除引用来修改容器值,而不能读取。(cout就是可以修改发送到显示器的字符流,而布恩那个读取屏幕上的内容)(适用于单通行只写算法)只能使用++运算符来遍历容器,与上述两个迭代器不同的是,它总是按
2024-11-26 08:45:24
332
原创 C++基础:函数声明
使用“= delete”将复制构造函数和复制赋值运算符标识为删除函数。优先使用删除函数,而非private未定义函数。习惯上,删除函数会被声明为public,而不是private。这是因为客户代码尝试使用某个成员函数时会先校验可访问性,再校验删除状态。这样一来,当客户代码试图调用某个private删除函数时,编译器只会报错该函数为private,这样得到的错误信息并不完善。
2024-11-24 17:23:10
442
原创 C++基础:枚举
枚举量的名字属于包含着这个枚举型别的作用域,这就意味着在这个作用域内不能有其他实体取相同名字。(不限范围的枚举型别)并且,限定作用域的枚举型别(enum class)是强型别的。不限范围的枚举型别中的枚举量可以隐式转换到整数型别(并能从此处进一步转换到浮点型别)还有,限定作用域的枚举型别可以前置声明,因此其型别名字可以比其中的枚举量先声明。但是不限范围的枚举型别也可以前置声明,前提是需要额外完成一些工作后。也就是选择一个整数型别作为其底层型别。
2024-11-24 15:50:17
112
原创 C++基础:函数对象
对于所有内置的算数关系符,关系运算符和逻辑运算符,STL都提供了等价的函数符。运算符相应的函数符plusminuxmultipliesdividesmodulusnegate==equal_to!
2024-11-21 08:32:45
412
原创 C++基础:模板类型推导
autodecltyperx的引用性会在类型推导过程中被忽略。rx的引用性会在类型推导过程中被忽略。对于上述案例,虽然都是用左值引用形参演示,但是右值引用形参的类型推导运作方式完全一致。也就是,传递左值给万能引用作为形参的函数,模板对应类型与该值类型一致。传递右值给万能引用作为形参的函数,模板对应类型为该值类型的右值引用。若具有引用类型。则忽略引用部分。忽略引用性之后,若param是const对象,也忽略const。若是个volatile对象,也忽略。因为param是一个独立于cx和
2024-11-19 09:10:01
438
原创 C++基础:右值引用,移动语义,完美转发
左值是一个表示数据的表达式(如变量名或解除引用的指针),程序可以获取其地址。C++11新增了右值引用,使用&&表示。即能出现在赋值表达式右面,但是不能对其应用地址运算符的值。包括字面常量(C风格字符串除外,它表示地址)、诸如x+y等表达式以及返回值的函数(条件是该函数返回的不是引用)将右值关联到右值引用导致该右值被存储到特定的位置,且可以获取该位置的地址。也就是说,虽然不能将运算符&用于13,但是可以用于r1。通过将数据与特定的地址关联,使得可以通过右值引用来访问该数据。
2024-11-17 00:31:07
166
原创 C++基础:输入、输出和文件
C++程序把输入和输出看作字节流。通过使用流,C++程序处理输出的方式将独立于其去向。因此管理输入包含两步:1 将流与输入去向的程序关联起来。2 将流与文件连接起来。通常,通过使用缓冲区可以更高效的处理输入和输出。缓冲区时用作中介的内存块,它是将信息从设备传输到程序或从程序传输给设备的临时存储工具。一些相关类iostream类的8个流对象。
2024-11-05 08:54:42
228
原创 C++基础:string类,智能指针,基础的标准模板库,迭代器
每当程序将一个字母附加到字符串末尾时,可能要分配一个新的内存块,并将原来的内容复制到新的内存单元中。然而,如果字符串不断增大,超过了内存块大小,程序将分配一个大小为原来两倍的新内存块。读取的字符数达到最大允许值,在这种情况下,将设置输入流的failbit,这意味着方法fail()将返回true。到达文件尾,在这种情况下,输入流的eofbit将被设置,这意味着方法fail(),eof()都将返回true。find_first_not_of():在字符串中查找第一个不包含在参数中的字符首次出现的位置。
2024-10-31 08:43:05
604
原创 C++基础:友元,嵌套类,异常,类型转换
友元类的所有方法都可以访问原始类的私有成员和保护成员。也可以只将特定的成员函数指定为另一个类的友元。
2024-10-24 23:13:13
268
2
原创 C++基础:继承
如果没有使用关键字virtual,程序将根据引用类型或指针类型选择方法;如果使用了virtual,程序将根据引用或指针指向的对象的类型来选择方法。如果析构函数不是虚的,则将只调用对应于指针类型的析构函数,这意味着只有基类的析构函数被调用,即使指针指向的是一个派生类对象。1 在派生类中重新定义基类方法。如果析构函数是虚的,
2024-08-19 08:20:44
173
原创 Git使用场景
建立源版本upstream,即你fork的项目地址查看当前仓库的远程仓库地址和原仓库地址,查看所有版本记录获取原仓库的更新。使用fetch更新,fetch后会被存储在一个本地分支upstream/master上。切换到想要合并的分支查看所有版本从upstream/current_branch拉取代码合并到本地分支。切换到本地master分支,合并upstream/master分支。在没有冲突时,会有如下的显示。这个时候编辑提交信息即可sdhkj在merge有冲突时,会有如下提示。
2024-07-20 11:38:46
462
原创 LeetCode矩阵类问题
要求使用原地算法,也就是不引入新的数组,在原有的数组上进行修改来解题。也就是使用额外两个变量来记录第一行第一列是否为0,然后勇第一行第一列记录其他行列是否为0.
2024-07-17 07:42:35
127
原创 RPC与HTTP
RPC 在我们熟知的各种中间件中都有它的身影。Nginx/Redis/MySQL/Dubbo/Hadoop/Spark/Tensorflow 等重量级开源产品都是在 RPC 技术的基础上构建出来的,我们这里说的 RPC 指的是广义的 RPC,也就是分布式系统的通信技术。RPC 在技术中的地位好比我们身边的空气,它无处不在,但是又有很多人根本不知道它的存在。HTTP 调用其实也可以看成是一种特殊的 RPC,只不过传统意义上的 RPC 是指长连接数据交互,而 HTTP 一般是指即用即走的短链接。
2024-07-15 12:10:15
464
原创 LeetCode数组类问题
这道题,每次遍历记录与下一个元素相加前是否保留之前的和,大于零就可以加,小于零,sum就值等于当前元素值,然后结果是当前元素值和结果的之间的最大值,然后接着往下遍历。
2024-07-15 07:52:46
153
原创 LeetCode滑动窗口类问题
将当前正在分析字串作为滑动窗口,设立i作为起始下标,j作为结束下标,Set记录当前字符串中元素,无重复j++并且往set添加元素,有重复时记录长度,然后i往前并且从set中剔除元素直到将与j重复的哪个元素剔除掉。438.找到字符串中所有的字母异位词。3.无重复字符的最长子串。
2024-07-14 18:34:09
186
原创 LeetCode题型分类
双指针 https://blog.youkuaiyun.com/FranYeCisco/article/details/140418344 11.盛水最多的容器 双指针 15.三数之和 双指针
2024-07-14 16:26:55
122
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人