- 博客(104)
- 收藏
- 关注
原创 Linux命令行与shell脚本编程大全(第4版) 第二部分shell脚本编程基
{}使用来包含命令的使用方括号浮点数解决方案bash 只支持整数运算的限制。exit 命令允许在脚本结束时指定一个退出状态码:退出状态码最大只能是 255。
2025-11-23 19:47:24
148
原创 《C++并发编程实战》 第2章 线程管控
为什么要用它们而不是直接用 it + n 或 it - it?因为不是所有容器(比如 std::list)都支持 + 或 - 运算符。使用 std::distance 和 std::advance 可以让你的并发算法适用于任何标准容器,增强了代码的通用性。当前线程的ID可以通过调用std::this_thread::get_id()获得。在与线程关联的std::thread对象上调用成员函数get_id()
2025-11-22 19:49:13
342
原创 Linux命令行与shell脚本编程大全(第4版) 第一部分 Linux命令行
Linux 系统可划分为以下 4 部分。 Linux 内核 GNU 工具 图形化桌面环境 应用软件内核主要负责以下 4 种功能。 系统内存管理 软件程序管理 硬件设备管理 文件系统管理。
2025-11-19 19:38:54
929
原创 GPU编程初探
推荐资料:CUDA编程入门PTX (Parallel Thread Execution) 是一种由 NVIDIA 定义的虚拟汇编语言(Virtual Assembly Language)。它不是针对特定硬件芯片的机器码,而是 CUDA 编程模型中的一个中间层表示(Intermediate Representation, IR)。你可以把 PTX 理解为 GPU 世界的 Java 字节码。它是一种标准的、跨代、跨架构的指令集,用于连接 CUDA 编译器和实际的 GPU 硬件。
2025-10-13 17:27:44
485
原创 C++并发编程-24. 几种简单并行算法的实现(for_each,find以及partial_sum)
前文介绍了几种数据划分的方式,包括按照线程数量划分,按照递归方式划分,以及按照任务类型划分等。本文结合之前的划分方式,基于stl的find, for_each以及partial_sum等算法实现并行版本。
2025-09-04 09:43:37
480
原创 C++并发编程-23. 线程间切分任务的方法
我们实现一个函数调用上面的封装快速排序本例中,parallel_quick_sort()函数(19处)把绝大部分功能委托给sorter类(1处),后者通过栈容器管理待排序的数据段(2处),并集中管控多个线程以并发执行任务(3处),从而以便捷的操作方式给出了代码实现。本例中,主要工作由成员函数do_sort()负责(9处),它借标准库的std::partition()函数完成数据分段(10处)。
2025-09-04 08:50:56
715
原创 C++并发编程-19. 利用引用计数实现无锁并发栈
前文我们通过风险指针的方式实现了无锁栈,但是也提出了一些弊端,比如每次pop都要从风险数组中选择一个空闲的节点作为标记。其次删除节点前要遍历风险数组对比节点是否被风险指针所指涉,如果被风险指针指涉则需放入待删列表。最后pop结束时也要回收待删列表中的节点,还要依次将待删列表中的节点和风险数组对比,如果未被风险指针指涉则需删除,否则跳过。但是这种方式多次遍历风险数组,会有性能损耗,我们提出一种新的解决方式,利用引用计数实现无锁并发的栈。在C++并发编程一书中提出了两个计数,一个外部计数,一个内部计数,二者加起
2025-09-03 08:55:32
280
原创 C++并发编程-18. 运用风险指针实现无锁栈(难)
术语“风险指针”是指Maged Michael发明的一种技法, 后来被IBM申请为专利。前文我们设计了无锁并发栈的结构,对于pop操作回收节点采用的是延时删除的策略,即将要删除的节点放入待删除列表中。但是待删列表中的节点可能永远不会被回收,因为每次多个线程pop就不会触发回收待删列表的操作。上一节我们说可以通过执行pop的最后一个线程执行回收,那为了实现这个目的,我们就要换一种思路。
2025-09-02 09:20:15
991
原创 C++并发编程-18. 线程安全的无锁栈(难)
前文我们通过锁的互斥机制实现了并发安全的栈,队列,查找表,以及链表等结构。接下来本文介绍通过无锁的原子变量的方式实现对应的容器,我们这一篇先从无锁的方式实现栈讲起。
2025-08-29 11:00:22
1036
原创 C++并发编程-17. 线程安全的链表
前文介绍了如何基于锁实现线程安全的栈和队列结构,以及实现线程安全的查找表,但是我们上次的查找表是基于list实现的,对于锁的精度控制的不是很准确,提及了接下来会介绍精细控制的链表,用来替换查找表中的链表。这一节我们就介绍如何通过锁控制链表访问的精度。
2025-08-29 09:18:11
964
原创 C++并发编程-16.实现线程安全的查找表
前文介绍了线程安全的队列和栈,本文继续介绍线程安全的查找结构,实现一个类似线程安全的map结构,但是map基于红黑树实现,假设我们要增加或者删除节点,设计思路是依次要删除或增加节点的父节点,然后修改子节点数据。尽管这种思路可行,但是难度较大,红黑树节点的插入要修改多个节点的关系。另外加锁的流程也是锁父节点,再锁子节点,尽管在处理子节点时我们已经处理完父节点,可以对父节点解锁,继续对子节点加锁,这种情况锁的粒度也不是很精细,考虑用散列表实现。
2025-08-28 10:01:05
1026
原创 C++并发编程-15. 基于锁实现线程安全队列和栈容器
我们实现了push操作和pop操作push操作里加锁,然后将数据通过std::move的方式移动放入stack中。我们思考如果1处因为机器内存不足push导致异常,此种情况并不会对栈已有的数据产生危险。但是vector容器大家要考虑,因为vector存在内存不足时将数据拷贝转移到新空间的过程。那么对于vector这种动态扩容的容器该如何保证容器内数据在移动过程中出现了异常仍能不丢失呢?
2025-08-13 12:00:14
443
原创 3. boost::asio之同步读写的客户端和服务器示例
前面我们介绍了boost::asio同步读写的api函数,现在将前面的api串联起来,做一个能跑起来的客户端和服务器。客户端和服务器采用阻塞的同步读写方式完成通信。
2025-08-01 11:57:26
435
原创 2. boost::asio socket同步读写
boost::asio提供了几种同步写的api,write_some可以每次向指定的空间写入固定的字节数,如果写缓冲区满了,就只写一部分,返回写入的字节数。
2025-07-25 11:19:04
284
原创 1. boost::asio之socket的创建和连接
网络编程的基本流程对于服务端是这样的服务端1)socket——创建socket对象。2)bind——绑定本机ip+port。3)listen——监听来电,若在监听到来电,则建立起连接。4)accept——再创建一个socket对象给其收发消息。原因是现实中服务端都是面对多个客户端,那么为了区分各个客户端,则每个客户端都需再分配一个socket对象进行收发消息。5)read、write——就是收发消息了。对于客户端是这样的客户端1)socket——创建socket对象。
2025-07-24 20:35:56
760
原创 C++并发编程-14. 利用栅栏实现同步
前文我们通过原子操作实战实现了无锁队列,今天完善一下无锁的原子操作剩余的知识,包括Relaese和Acquire内存序在什么情况下是存在危险的,以及我们可以利用栅栏机制实现同步等等。
2025-07-18 21:45:10
422
原创 C++并发编程-13. 无锁并发队列
前文介绍了如何通过内存顺序实现内存模型,本文基于前文的基础,利用内存顺序和内存模型的知识,带着大家探索无锁并发的应用,主要是通过无锁队列的实现来让大家熟悉无锁并发的实现方式。
2025-07-18 11:49:07
781
原创 C++并发编程-12. 用内存顺序实现内存模型
前文我们介绍了六种内存顺序,以及三种内存模型,本文通过代码示例讲解六种内存顺序使用方法,并实现相应的内存模型。全局一致性模型同步模型(获取和释放)松散模型上面的代码load和store都采用的是memory_order_relaxed。线程t1按次序执行1和2,但是线程t2看到的可能是y为true,x为false。进而导致TestOrderRelaxed触发断言z为0.如果换成memory_order_seq_cst则能保证所有线程看到的执行顺序是一致的。上面的代码x和y采用的是memory_ord
2025-07-10 22:02:09
589
原创 C++并发编程-11. C++ 原子操作和内存模型
本文介绍了3种内存模型,包括全局一致性模型,同步模型以及最宽松的原子模型,以及6种内存序,下一篇将介绍如何利用6中内存序达到三种模型的效果。
2025-07-09 22:24:46
1019
原创 C++并发编程-8. 利用并行和函数式编程提升计算效率
这种实现方式比较依赖存储数据的数据结构,比如上面是通过数组存储的,那如果我想实现list容器中元素的排序怎么办?我既不想关注存储的容器,也不想关注存储的类型,想实现一套通用的比较规则?那就需要函数式编程来解决C++函数式编程是一种编程范式,它将计算视为数学上的函数求值,并避免改变状态和使用可变数据。在函数式编程中,程序是由一系列函数组成的,每个函数都接受输入并产生输出,而且没有任何副作用。在C++中,函数式编程可以使用函数指针、函数对象(functor)和lambda表达式等机制来实现。这些机制允许您编写可
2025-07-05 14:50:53
944
原创 C++并发编程-7.C++ 并发三剑客future, promise和async
在这个示例中,std::async 创建了一个新的线程(或从内部线程池中挑选一个线程)并自动与一个 std::promise 对象相关联。std::promise 对象被传递给 fetchDataFromDB 函数,函数的返回值被存储在 std::future 对象中。在主线程中,我们可以使用 std::future::get 方法从 std::future 对象中获取数据。注意,在使用 std::async 的情况下,我们必须使用 std::launch::async 标志来明确表明我们希望函数异步执行。
2025-07-05 08:24:53
823
原创 C++并发编程-6.利用条件变量实现线程安全队列
本文介绍如何使用条件变量控制并发的同步操作,试想有一个线程A一直输出1,另一个线程B一直输出2。我想让两个线程交替输出1,2,1,2…之类的效果,该如何实现?有的同学可能会说不是有互斥量mutex吗?可以用一个全局变量num表示应该哪个线程输出,比如num为1则线程A输出1,num为2则线程B输出2,mutex控制两个线程访问num,如果num和线程不匹配,就让该线程睡一会,这不就实现了吗?比如线程A加锁后发现当前num为2则表示它不能输出1,就解锁,将锁的使用权交给线程A,线程B就sleep一会。Po
2025-06-29 21:06:35
317
原创 C++并发编程-5.C++ 线程安全的单例模式演变
本文介绍C++ 线程安全的单例模式如何实现,通过介绍单例模式的演变历程,给读者更完备的实现单例模式的方案。上述版本的单例模式在C++11 以前存在多线程不安全的情况,编译器可能会初始化多个静态变量。但是C++11推出以后,各厂商优化编译器,能保证线程安全。所以为了保证运行安全请确保使用C++11以上的标准。注意下面的介绍都是C++11标准11以前单例模式的演变历程,C++11以后就直接写成上面哪个就OK,因为C++11要求各厂商必须在多线程的情况下保证静态变量初始化的安全性饿汉式是从使用角度规
2025-06-29 20:01:05
641
原创 C++并发编程-4.unique_lock,共享锁和递归锁
也就是说读操作并不是互斥的,同一时间可以有多个线程同时读,但是写和读是互斥的,写与写是互斥的,简而言之,写操作需要独占锁。如果我们想构造共享锁,可以使用std::shared_lock,如果我们想构造独占锁, 可以使用std::lock_gurad.我们用一个类DNService代表DNS服务,查询操作使用共享锁,而写操作使用独占锁,可以是如下方式的。要想使用共享锁,需使用共享互斥量std::shared_mutex,std::shared_mutex是C++17标准提出的。但是我们可以使用递归锁。
2025-06-27 22:02:09
894
原创 代码随想录-高级篇之动态规划算法
public:// 总体思路:让重量相近的石头先碰撞。// 石头分成两堆:总和一半/2,总和-总和一半的一堆 而且 前一堆>后一堆 向下取整// 最后的结果:/*动规五部曲1. dp[j]的含义重量为j的背包的最大价值为dp[j]2. 递归表达式3. 初始化dp[0] = 0;所有初始化为04. 遍历顺序5. 打印*/++i) // 先遍历物品--j) // 遍历背包,从大往小遍历{ // j >= stones[i] 背包容量不能小于石头的容量。
2025-06-24 18:44:56
739
原创 C++并发编程-2.C++ 线程管控
参考:https://llfc.club/category?catid=225RaiVNI8pFDD5L4m807g7ZwmF#!aid/2Tuk4RfvfBC788LlqnQrWiPiEGW使用起来比较简单,我们直接构造一个joining_thread对象即可。5. 选择运行数量借用C++标准库的std::thread::hardware_concurrency()函数,它的返回值是一个指标,表示程序在各次运行中可真正并发的线程数量.我们可以模拟实现一个并行计算的功能,计算容器内所有
2025-06-17 22:33:56
441
2
原创 11.王道_workflow
/ 计数器//计数器减一// 阻塞主线程,直到按住Ctrl+Cint main()// 等待直到计数器减一freturn 0;
2025-05-15 10:32:40
888
原创 10.王道_HTTP
nlohmann/json是一个header-only的C++ json解析库,可以用于构造和解析JSON对象。键值必须是字符串数据-》字节流:序列化/编码字节流-》数据:反序列化。解码"sites":"site":"name":"王道论坛",},"site":},"site":"name":"微博",
2025-05-08 16:24:59
1133
原创 代码随想录-高级篇之贪心算法
贪心,计算每个站点剩余的,当累加小于0时,以下一站点为起始点开始计算。注意:下标为i的元素的覆盖范围是:i+cover[i]从后往前两个数字两个数字变量遍历。贪的时每次的最大覆盖范围。
2025-04-28 18:20:51
476
原创 8. 王道_网络编程
域名和IP地址的对应关系如何排查网络故障阿强断开重连:客户端终止服务端仍然可以接受新连接accept本质上是一个读操作,读的对象就是分配监听队列中的连接,所以可以使用select监听。这样就可以有新连接到来再做accept操作,这样服务器既可以处理旧连接的收发和新连接的建立当有多个客户端发送消息时,分不清是谁是谁,因为没有像TCP的netfd使用UDP的即时聊天断开连接对方不知道sendto可以发送长度为0的报当主动方要退出时
2025-04-08 14:57:47
789
原创 代码随想录-高级篇之回溯算法
当你举例子,需要不断用到循环时,这时候就要想到回溯,首先应该举例子,画出树形图,递归函数 + for循环回溯方法—纯暴力方法模板。
2025-03-29 17:40:09
437
原创 6.王道_线程
在创建所有线程之后立即销毁了条件变量和互斥量,这是不正确的,因为这些资源在线程运行期间还需要被使用。你应该将pthread_cond_destroy(&share.cond);和pthread_mutex_destroy(&share.mutex);这两行移动到所有线程结束(即调用pthread_join之后)的位置。设置mutex(检错锁和递归锁)的属性来避免第三种死锁类型。只有自己加锁,再加锁才会报错,别人加锁,我再加锁不会报错。作业,A再B之前执行。
2025-03-29 09:35:28
503
原创 5.王道_信号
通常这种状态出现在进程必须不受干扰地等待或者等待事件很快会发生的 时候出现,比如进程正在等待磁盘读写数据的时候。内核不可中断状态是进程等待态的一种形式。mask刚开始为空,当递送信号的过程中会触发一个临时屏蔽,mask会包含这个触犯的信号,当从递送返回的时候mask会删除这个信号。屏蔽的过程中如果产生信号会放入pending中.pending只放一个信号。处于内核不可中断状态(进程控制块的state成员此时为TASK_UNINTERRUPTIBLE)的进程。处于这种的状态的进程在 ps 中显示为。
2025-03-23 10:56:41
294
原创 4.王道_进程间通信
共享内存可以在两个互不关联的进程之间进行通信,只需要彼此之间知道共享内存的键就好了。先后执行shm_w和shm_r程序,后一个进程可以读取共享内存中前一个进程写入的信息。在fork之前打开的文件对象,在fork之后是共享的。只读不写会阻塞,只写不读不会阻塞。
2025-03-22 09:18:42
432
原创 3.王道_进程
粘滞位(Stickybit),或粘着位,是Unix文件系统权限的一个旗标。最常见的用法在目录上设置粘滞位,如此以来,只有目录内文件的所有者或者root才可以删除或移动该文件。如果不为目录设置粘滞位,任何具有该目录写和执行权限的用户都可以删除和移动其中的文件。实际应用中,粘滞位一般用于/tmp目录,以防止普通用户删除或移动其他用户的文件。
2025-03-20 19:18:09
956
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅