- 博客(15)
- 收藏
- 关注
原创 唤醒丢失(Lost Wakeup)—— 以c++线程池为例
测试代码中没出问题,可能是因为刚好没卡上这个情况,也有可能是操作系统的调度策略,导致条件变量导致休眠后,可能有虚假唤醒(Spurious Wakeup)的情况。可能被主线程修改,也可能被生产者线程读取,所以我就想用原子变量来操作。在自己实现线程池的时候犯了一个多线程编程中的错误——唤醒丢失(Lost Wakeup)这里的while循环就可以保证虚假唤醒不影响程序的正确逻辑。的wait操作中的谓语(predicate)为。,阻塞队列的Pop、Cancel操作如下,所以正确的Cancel函数应该是这样的。
2025-12-09 20:37:58
195
原创 用shared_ptr举例从CPU角度说明:原子变量的线程安全=原子性+内存序
所以ref_count++只用保证计数精准就行,因为在最后一个ref_count–之前,所有的ref_count++必会全部执行完。对同一个引用计数的fetch_add是一定在fetch_sub前面的,所以在fetch_sub之前,引用计数至少是1的,这就保证了ptr_不会被析构,当p1放弃ptr_的时候,p2的fetch_add是一定会加上的。析构函数在逻辑上的意义就是,放弃对ptr_的使用权了,所以对ptr_的操作只会出现在析构函数之前。,而不可能是两个线程同时将ref_count_减到了。
2025-11-30 16:38:16
867
原创 多核CPU——MESI 协议
保证了**“只要数据写进了缓存,大家看到的都是一样的”**。这是硬件底线。为了快,“写操作”被暂存了,没立刻进缓存。导致只有自己看得到,别人看不到。不是数据丢了,而是**“生效的时间差”导致了观察顺序的错乱**(看起来像代码乱序执行了)。是一条强制命令,告诉 CPU“别偷懒,把发件箱里的东西发完了再做下一件事”。这就是为什么在 Java 中写volatile,或者在 C++ 中用时,编译器会在底层自动帮你插入这一条“内存屏障”汇编指令,从而保证程序的正确性。
2025-11-26 15:32:50
659
原创 std::future & std::promise原理(c++11)
因为mysql线程池中用到了c++11新特性 std::future & std::promise,所以在这里简单了解一下std::future & std::promise的底层实现原理,以便更好的实现mysql线程池。
2025-11-21 15:48:40
142
原创 从原理开始实现c++线程池
在网络服务器中,解决了底层的网络连接处理和网络包处理之后,剩下的就是业务处理,客户端来了一个包后,服务器解析包中包含的数据,然后处理。时,如果直接在网络IO线程进行处理的话,那么IO线程就会阻塞,导致其他的所有连接的消息几秒钟甚至几分钟得不到处理,这就是非常严重的延迟事故了。因为CPU的核心数量是固定的,当线程数量超过CPU的核心数时,此时就会带来。正如前面所说,线程池是维持管理一定数量线程的池式结构,那么这个一定数量就需要去确定一个值。的代价,如果线程数量过多时,可能效率还不如不用线程池。
2025-11-18 16:03:51
12144
原创 key-value存储——封装三种通信模式reactor、proactor、协程为网络层(1/4)
在proactor、reactor以及协程上传输协议的架构。设计成可以自由选择网络框架的模式,想用proactor、reactor或者协程都行。故无论是哪一种网络框架,都可以设计为只暴露一个接口,这个接口只接受两个参数。无论是proactor、reactor或者协程都只暴露一个接口,也就是。因为无论是何种网络框架,起到的作用无非就是。,然后交给上层模块处理数据,然后将上层网络。为什么只用暴露这一个接口呢?
2025-11-02 21:03:14
302
原创 c语言编译链接时出现错误 multiple definition of ’变量名‘
头文件被多个 .c 文件 #include,如果头文件里包含了实际的定义(例如 char command[256];),那么每个包含该头文件的 .c 编译后都会生成一份该符号的定义(各自的 .o 文件都有),链接器把这些 .o 合在一起时就会发现同名的全局符号出现多次,产生 multiple definition 错误。把定义只放在一个 .c 文件里,其他地方用 extern 声明,就只会有一个实际的存储分配,链接器就不会报错。每个 .c 在预处理后形成一个翻译单元(translation unit)。
2025-11-02 19:42:00
242
原创 什么是io_uring?异步io机制和同步io机制的区别是什么?proactor和reactor的区别是什么?如何用io_uring实现proactor?
同步io写请求和发送数据是一起的读请求和返回数据是一起的(copy_to_user)也就是当调用read的时候,read里面是一定会去读数据,如果有数据就会放入buffer的。异步io中,读请求、写请求和返回数据、发送数据。在异步io中,调用异步read的时候,异步read里面并不会去读数据,而只是发送了一个,下面在io_uring的解释中,会详细说明读请求是什么东西。
2025-10-27 13:55:51
1027
原创 什么是协程?如何用c实现协程?
开始定义协程,用于网络io框架处理每一个协程需要有以下的成员变量,当然实际实现代码中可能还有其它变量用于存储协程诞生时间、协程名等等。int fd;// 网络io肯定需要fd// 保存协程的上下文// 协程回调函数void* arg;//回调函数参数;int status;//协程状态其中用于组织每个协程的有三个数据结构,分别是一个队列来存储状态为READY的协程,两个红黑树用来存储WAIT和SLEEP状态的协程。协程调度器最少要有以下的成员// 用于监测协程事件。
2025-10-23 15:24:59
928
原创 什么是Reactor(linux c)
顾名思义,就是根据不同的情况起不同的反应,也就是根据不同的事件调用不同的回调函数,即为编程中的reactor。
2025-10-17 13:26:00
868
原创 linux服务器网络tcp io系统调用
一个最小可运行的 TCP 服务器一般包含以下系统调用(从创建到关闭):socket()bind()listen()accept()辅助调用fcntl()tcp现有的连接被存储在:/proc/net/tcp。
2025-10-17 10:53:31
255
原创 基于epoll与reactor模式的百万并发服务器以及百万连接测试(linux c)
基于epoll与reactor模式的百万并发服务器reactor epoll 百万并发 百万连接 连接测试
2022-01-14 20:21:22
511
原创 reactor的原理与实现(linux c)
reactor 原理与实现 水平触发LT 边沿触发ET 水平触发与边沿触发的区别什么是reactor
2022-01-13 18:04:26
532
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅