- 博客(37)
- 收藏
- 关注
原创 《从零构建高性能HTTP服务器》(3)线程池架构,实现多线程同步服务
本文介绍了如何将单线程服务器改造为多线程服务器,以提升并发处理能力。主要内容包括:1)线程池设计原理,通过任务队列、工作线程组、同步机制和生命周期管理四大组件;2)核心代码实现,详细解析了生产者-消费者模式、条件变量等待等关键技术;3)性能测试对比,在5000请求/200并发场景下达到4953req/s的吞吐量。文章还讨论了C++现代多线程编程的优势,并指出后续优化方向,如添加异步日志和IO多路复用技术。
2025-10-14 00:05:36
924
原创 《从零构建高性能HTTP服务器》(2)封装 HTTP服务器 类
上文我们在主函数里调用socket接口实现了一个服务器的功能,但不够灵活,不能随意修改。本文就针对上次的代码进行面向对象的封装,使其成为一个简单的服务器类,以便于后续的扩展。
2025-10-10 00:06:27
187
原创 《从零构建高性能HTTP服务器》(1)30行C++代码实现我的第一个HTTP服务器
本文记录了一个开发者从零开始用C++和Socket API实现简易HTTP服务器的过程。文章详细介绍了创建socket、绑定端口、监听连接、接收请求并返回"Hello World"响应的完整代码实现(约30行),重点讲解了关键系统调用和网络编程概念(如字节序转换、地址结构转换等)。这个单线程阻塞式服务器虽简陋,但为后续升级(多线程、HTTP解析、性能测试等)奠定了基础。作者通过实践体会到:不要等待完美才开始,从小项目着手解决问题才是最高效的学习方式。
2025-10-09 12:56:20
730
原创 Linux学习记录--利用信号量来调度共享资源(2)
策略优点缺点适用场景读者优先读并发度高写者可能饥饿读多写少写者优先写者不会饥饿读并发度低写操作重要进一步优化:可以实现公平的读者-写者算法,避免任何一方饥饿,如使用额外的队列管理等待顺序。实际应用:数据库系统的并发控制、文件系统的读写锁等都基于读者-写者问题的解决方案。
2025-09-25 21:40:30
838
原创 Linux学习记录--用信号量建立秩序:让多线程不再踩脚
信号量是一种用于线程同步的机制,通过P(等待)和V(发信号)原子操作实现对共享资源的互斥访问。P操作在信号量为零时阻塞线程,V操作释放资源并唤醒等待线程。使用POSIX信号量接口(如sem_init、sem_wait、sem_post)可初始化、加锁和解锁二元信号量(互斥锁)。通过将临界区代码(如计数器操作)用P/V操作包围,能有效解决多线程竞争问题。信号量不仅用于互斥,还可调度共享资源。
2025-09-25 11:45:23
1018
1
原创 Linux学习记录--利用信号量来调度共享资源(1)
本文介绍了生产者-消费者问题的解决方案,重点讲解了使用信号量实现线程同步的技术细节。文章首先区分了二元信号量和计数信号量的不同用途,随后详细解析了环形缓冲区的实现(sbuf_t结构),特别强调了P操作的顺序问题:必须先获取资源信号量(slots/items)再获取互斥锁(mutex),否则会导致死锁。文中提供了完整的代码示例,包括缓冲区初始化、生产者插入和消费者移除的实现,以及一个多线程测试案例。最后总结了常见错误模式,如死锁、段错误等,并预告了下期将讨论的读者-写者问题。该方案通过合理使用信号量,有效解决
2025-09-24 00:21:43
566
原创 Linux学习记录--多线程共享变量
多线程编程中的共享变量既是协作工具也是潜在陷阱。本文通过两个案例揭示了共享变量的双面性:在sharing.c中,线程通过共享指针安全读取不同数据;而在badcnt.c中,多线程同时写计数器导致数据竞争,结果出现偏差。关键发现是:只读共享安全,读写共享需同步机制。作者将共享变量比作公共厨房的调料架,多人同时使用时需要排队规则(如信号量),并预告下一篇将介绍如何用信号量解决并发冲突。文章强调共享变量不是不能用,而是需要正确使用同步机制来保证线程安全。
2025-09-23 18:45:44
785
原创 Linux学习记录--终止线程
本文介绍了线程终止的四种方式:1)线程例程返回隐式终止;2)pthread_exit显式终止;3)exit函数终止进程及所有线程;4)pthread_cancel终止指定线程。重点通过四个代码示例(pthread_exit、pthread_cancel、线程自取消和exit误用)演示了不同终止方式的特点:pthread_exit/return仅终止当前线程;pthread_cancel需到达取消点才生效;exit会直接终止整个进程。文章还总结了POSIX规定的取消点函数特征(多为阻塞操作),并提醒在纯CPU
2025-09-22 17:20:58
529
原创 Linux学习--初识线程
本文介绍了线程的基本概念和核心API。线程是运行在进程上下文中的逻辑流,共享进程的虚拟地址空间,但拥有独立的线程上下文。文章详细讲解了pthread_create、pthread_exit、pthread_join等核心API的使用方法,并通过三个示例程序演示了线程创建、回收和并发执行。特别强调了多线程编程中需要注意的四个关键点:线程ID参数传递、函数签名规范、返回值处理方式以及线程回收顺序。这些内容为理解和使用线程提供了基础指导。
2025-09-17 00:16:06
365
原创 Linux学习记录--消息队列
本文介绍了Linux系统中的POSIX消息队列(Message Queue)机制及其核心API。消息队列是一种支持优先级、异步通信的IPC方式,相比管道等传统方法具有结构化消息、内核持久化等优势。文章详细对比了不同IPC机制的特性,重点讲解了mq_open、mq_send等核心函数的使用要点,包括参数设置、错误处理和注意事项。通过实际代码示例演示了消息队列的创建、读写操作和优先级特性,并展示了跨进程通信的实现方法。最后指出当前示例仅为基础用法,后续可进一步优化性能。文章为开发者提供了POSIX消息队列的实用
2025-09-10 22:51:18
1038
1
原创 Linux学习记录--共享内存空间SHM
Linux 共享内存(Shared Memory)是一种进程间通信(IPC)机制,它允许多个进程访问同一块物理内存区域,从而实现高效的数据共享。多个进程将同一段物理内存映射到自己的虚拟地址空间中,使得一个进程对共享内存的修改可以立即被其他进程看到。
2025-09-02 11:45:29
675
原创 Linux学习记录--命名管道FIFO
命名管道(FIFO)是一种系统级进程通信机制,通过特殊的文件节点实现任意进程间的单向通信。与匿名管道不同,FIFO在文件系统中可见,进程通过open()打开后即可读写。典型使用流程包括:mkfifo创建管道文件、open打开、read/write读写数据、close关闭以及unlink删除文件节点。FIFO作为内核缓冲区不持久存储数据,使用时需注意清理以避免产生"僵尸管道"。其实质是内核管理的临时通道,适合本机进程间通信场景,但要注意默认64KB的缓冲区限制和生命周期管理。
2025-08-30 23:51:54
915
原创 c++ 基础 运算符重载(二)
-《c++ primer 中文版 第五版》不可重载的运算符不可重载的运算符以下运算符不可重载和.*?sizeoftypeidnewdelete(只能重载全局版本,不可作为成员函数重载)如何确定运算符重载为成员函数还是普通函数赋值(=),下标记([]),调用(())和成员访问箭头(->)运算符必须是成员。复合赋值运算符一般来说应该是成员,但并非必须,这一点与赋值运算符略有不同。改变对象状态的运算符或者与给定类型密切相关的运算符,如递增,递减和解引用运算符,通常应该是成员。
2025-03-16 20:53:06
712
原创 SQL Server 查询操作
在上文中,简单介绍了数据库以及表格的建立,相信大家都迫不及待想查询其中添加数据,那么本文将带领大家去查询表中数据.注:中括号内容可无,尖括号起到区分作用,实际代码不写。
2024-04-06 21:36:21
1712
1
原创 C语言数据结构基础 图的深度优先遍历
图作为一种复杂的数据结构,也存在遍历问题。图的遍历就是从图中的某个顶点出发,按某种方法对图中的所有顶点访问且仅访问一次,图的遍历算法是求解图的连通性问题,拓扑排序和关键路径等算法的基础。图的遍历比起树的遍历要复杂得多。由于图中顶点关系是任意的,即图中顶点之间是多对多的关系,图可能是非连通图,图中还可能存在回路,因此在访问了某个顶点后,可能沿着某条路径搜素后又回到该顶点上。
2023-12-23 23:58:10
722
1
原创 C语言数据结构基础 图 的基本操作
图(Graph)是一种网状数据结构,由许多结点以及结点间的关系构成。当然,一个结点也算图,就是一个结点无法蕴含太多关系罢了。其形式化定义如下:R={ VR }DataObject 为一个集合,该集合内所有元素具有相同的特性。V中的数据元素通常称为顶点(Vertex),VR是两顶点之间的关系的集合。P(x,y)表示x和y之间有特定的关联属性P。通俗点就是都具有R关系的顶点V构成了图Graph。
2023-12-23 22:32:11
2144
1
原创 C语言 数据结构基础 串的应用---文本处理系统
将文本看作一个大的字符串,文本处理也就是对字符串的处理。文本处理的实质就是修改字符数据的形式和格式,虽然各个文本编辑程序功能不同,但基本操作就是串的查找,插入,修改等。这里采用堆串结构,将整个文本看作一个字符串存放在堆区对其进行处理,不灵活,只能实现一些基本操作。在堆串的基础操作上,只需要利用堆串的函数,实现以下操作,就可以。
2023-11-19 17:16:44
290
原创 C语言基础 栈与递归
递归就是,从前有个山,山里有个庙,庙里有个老和尚给小和尚讲故事,讲的故事是,从前有个山,山里有个庙,庙里有个老和尚给小和尚讲故事,讲的故事是。。。就像套娃一样,在自己内部重复自己的过程,专业地讲叫:在定义自身的同时,又出现对自身的引用,* 如果一个函数在其定义体内直接调用自己,则称为直接递归函数* 如果一个函数经过一系列的中间调用语句,通过其他函数间接调用自己,则称为间接递归函数许多数学函数都是递归定义的,如二阶斐波那契(Fibonacci)数列定义为。
2023-10-22 21:00:51
444
1
原创 C语言 链表 案例
改进:利用head->Date/遍历操作,找到该链表的尾结点,在尾结点后插入元素或者化繁为简,将前驱上的操作经过赋值操作改编为后继结点上的操作,更为简单。
2023-10-03 21:58:23
236
原创 C++基础 -- 位运算 + 图像像素
所以,就以 00000000 11111111 10101010 01010101 为例 ,要保留后四位,前面全部变为零,可以将这个值。再通过内存溢出 32/64 位 只要向左或向右移动(位运算) 移动到32/64 位之外,便会溢出,损失溢出数据,而前后由0补齐。X,Y 为图像在窗口的坐标 (坐标原点在屏幕左上角,向右为X正半轴,向下为Y正半轴)如何只保留后八位呢 可以通过位运算 & |!* 非运算 ---!* 或运算 --- 有 1 就是1。----位运算-----和运算--- 有0就是0。
2023-08-03 22:03:19
576
原创 C++基础 链表
不能体现链表的灵便,同时只有尝试过任意位置增删结点,或者重新排序,才能体验到链表与数组的区别;下面首先展现一种动态链表的实现案例。因为链表并非固定的连续的存储空间,每个结点依靠指针域链接,故只需要更改相应结点指针域的指向,便可以实现链表的增删,排序操作。而根据 头结点和尾结点 存储的地址不同,又可以设计双向普通链表,也就是有头有尾,头以前指向空,尾以后指向空;所谓循环,就是单向链表头尾相连,形成闭环,也就是 尾部结点的指针域 存储 头结点的地址。* 常见有 单向链表,双向链表,循环链表,动态链表。
2023-07-27 22:39:57
221
1
原创 多态进阶--纯虚函数 抽象类
以上面的案例为例,可以看出,将制作饮品的公共步骤抽象出来后,再运用多态,那么对于不同饮品的制作,只需要再新建一个子类就可以实现,改变某个饮品的制作步骤,也不需要对全篇的代码进行修改,只用在其对应的子类对象修改即可。比如 如果想扩展一个做可乐之类,也很容易,只要在后面添加做可乐的子类就ok了。以上就是对多态的进一步认识,希望对大家有所作用。
2023-05-07 22:26:27
88
2
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅