53. 线程池


一般在web服务端使用线程池是比较常见的, 本节呢, 就已以实现一个简单的web服务端为目标, 仅仅实现GET请求, 最多在加上POST请求.

如果对web服务端并不熟悉的, 可以回过头去看一下http请求与应答以及一个500行左右的web服务端源码tinyhttpd(整理了源码以及修改和加注释后的linux版本).


线程池主要函数

线程池完整代码位置 : threadpool


因为线程池的代码大概有1000行吧, 没有办法全部进行分析, 所以我就将部分重要的函数罗列出来以便大家看到时候能够清楚.

  • initpool : 初始化线程池. 默认是创建的线程的个数是10个.
  • append : 将 http 事件加入到就绪队列中(就绪队列是由线程池中的所有进程共享的).
  • run : 当有事件就绪, 则线程池中的所有线程都被唤醒争夺资源, ,每个事件都只能有一个线程处理.

  • readn : 负责将内核缓冲区的数据赋值到 httdp 事件中的读缓冲区中.
  • writen : 负责将 httdp 事件中的写缓冲区数据赋值到内核缓冲区中并发送.
  • process_read : 分析 http 消息. 即分析 http 请求消息的行, 头部和消息体部分.
  • process_write : 负责将事件请求的文件内容放入 httdp 事件的写缓冲区中, 并通知主进程写事件准备就绪. 最终由主进程负责应答.

主函数

这里我们主函数的代码粘贴了一下, 打算用主函数的过程来分析整个简单的流程.

  1. 初始化线程池.
  2. 将套接字监听事件注册到 epoll 监听中.
  3. 有套接字监听事件就绪, 以 inithttpd 函数将其初始化.
  4. 客户端发送 http 请求后, 由 readn 函数将请求复制到 httpd事件的读缓冲区中.
  5. append 将 httpd 事件加入到就绪队列中.
    • 线程池中线程 调用processing : 解析请求, 分离请求方式(GET还是POST等), http 版本, 请求文件.
    • 并将请求的文件打开, 将数据复制到 httpd事件的写缓冲区中. 写入完成后通知主进程写事件就绪.
  6. 主进程调用 writen 函数将 httpd事件的写缓冲区数据发送给客服端, 完成一次应答.
int main(int argc, char *argv[]){
	int listenfd, clientfd;
	struct sockaddr_in addr;
	struct threadpool pool;

    ....
        
	initpool(&pool);
	// 将 listen监听描述符加入 epoll 的监听队列中并设置为非阻塞
	add_event(epollfd, listenfd, 0);

	int n;
	while(1){
		n = epoll_wait(epollfd, evs, sizeof(evs), -1);
		for(int i = 0; i < n; ++i){
			int fd = evs[i].data.fd;
			if(fd == listenfd){
				socklen_t len;
				struct sockaddr_in addr;
				len = sizeof(addr);
				clientfd = accept(listenfd, (struct sockaddr *)&addr, &len);
				if(clientfd < 0){
					fprintf(stderr, "accept error\n");
					continue;
				}
				inithttpd(&users[clientfd], clientfd, (struct sockaddr *)&addr);
			}
			else if(evs[i].events & (EPOLLRDHUP | EPOLLHUP | EPOLLERR))
				close_conn(&users[fd]);
			// 读事件就绪 : 
			// readn 将从缓冲区中将 http 请求读入到 httdp 读缓冲区中
			// append 将事件加入到就绪队列中, 由线程池中的线程处理
			else if(evs[i].events & EPOLLIN){
				if(readn(&users[fd]))
					append(&pool, &users[fd]);
				else 
					close_conn(&users[fd]);
			}
			// 写事件就绪 : 
			// writen 将 http 状态码以及请求的静态文件发送给客户端
			// 如果发送过程中出现问题则断开连接
			else if(evs[i].events & EPOLLOUT){
				if(writen(&users[fd]) == -1)
					close_conn(&users[fd]);
			}
		}
	}

	return 0;
}


小结

因为代码有很多, 这里也不好一一的讲解, 所以还是希望有兴趣的可以看一下源码, 也可以添加其他的功能(如 : 内存池等)实现成自己的小项目, 如果有问题也欢迎指出.


TinyHTTPd 源码分析

根据Java,JavaScript,mysql,c语言,vue3,回答下列问题 1.什么是面向对象编程? 2.Java中的集合包括什么? 3.spring boot三个架构? mapper的作用 4.Mybatis mapper.xml的配置映射 5.Radis 数据结构 6.Redis数据一致性问题 7.Mysql 数据结构 char和varchar的区别 8.Vue生命周期,钩子函数,响应式变量,npm,常用的element -ui 9.springboot常用注解有哪些 10.Nnginx 11.Rocketmq消息延迟 12.Mybatis用法 13.Arralist用过哪些api 14.遍历集合有哪几种 15.MySQL数据类型用过哪些 16.Date和datetime的区别 17.Git常见命令 18.Html标签通常有哪些 css 19.数据采集与分析用的哪个库 20.可视化用的什么技术 21.拦截器 22.常见异常 23.事务 24.组件通信,父组件如何给子组件传递信息 25.路由组件 26.反射 27.线程池,多线程 28.什么是注解(标记) 29.Aop 30.Git 31.idea常用插件 32.什么是反向代理 33.第三方接口 34.Lombok用法 35.Vue3常用的api 36.列举vue3的常用生命周期 37.Vue router 38.遍历数组的方法 39.Foreach和map的区别(有返回值) 40.Radis数据类型? 41.多态 42.Hashmap遍历方式 43.Springboot配置文件的相关知识 44.前端三件套 45.数据库与其外键的主要内容 46.常见表的关系 47.若依框架 48.Nginx相关内容与配置文件 49.Linux命令 50.后端接口怎么定义的 51.前端如何搭建 52.数据库常见的相关命令语句 53.数据库表设计 54.V-if 55.V-show
04-28
<think>好的,我需要处理用户关于多种IT技术的详细解释和使用方法的请求。首先,我要确保回答结构清晰,分点列出每个技术点,同时遵循用户给出的系统级指令,比如正确使用LaTeX格式、生成相关问题等。 用户提到的技术非常多,涉及Java、JavaScript、MySQL、C语言、Vue3、SpringBoot、Mybatis、Redis、Vue生命周期、Spring注解、Nginx、RocketMQ、数据结构、事务、组件通信、路由、反射、多线程、注解、AOP、Git、IDEA插件、反向代理、第三方接口、Lombok、Vue3 API、Vue路由、遍历数组、Redis数据类型、多态、HashMap遍历、SpringBoot配置、前端三件套、数据库设计、V-if和V-show。我需要逐一解释这些技术,但要注意不要过于冗长,保持每个部分的简洁明了。 首先,我需要确认每个技术点的核心概念和常见用法。例如,Java的多线程可以通过实现Runnable接口或继承Thread类;Vue生命周期包括created、mounted等钩子函数;Spring注解如@Autowired用于依赖注入。同时,需要确保技术细节的准确性,比如在解释数据结构时,提到栈和队列的区别;在数据库设计时,强调范式和索引的重要性。 接下来,生成相关问题时要覆盖各个技术点,并考虑用户可能感兴趣的进阶问题,比如性能优化、常见问题解决方案、技术对比等。例如,如何优化SpringBoot应用性能?V-if和V-show的使用场景区别是什么? 还需要注意引用用户提供的参考内容,但根据系统指令,引用标识需自然添加。不过用户提供的引用似乎主要是关于SpringBoot和Vue的项目搭建,可能在这些部分适当引用,但大部分技术点需要依靠自己的知识库来回答。 最后,检查LaTeX格式是否正确,所有行内公式用$...$,独立公式用$$...$$,例如在解释多态时,可能需要用代码示例而非数学公式,但如果有涉及算法复杂度的地方,比如快速排序的时间复杂度O(n log n),需要用LaTeX格式化。同时确保中文回答,语法正确,避免任何Markdown格式错误。 现在开始组织内容,分技术点进行简明扼要的解释,每个部分保持一两句话,然后生成相关问题。需要确保覆盖用户提到的所有技术,但不要遗漏。如果某些技术关联紧密,可以合并解释,比如前端三件套(HTML、CSS、JavaScript)可以一起说明。对于像Spring注解和AOP这样的Spring相关技术,可以分组讨论。同样,Vue3相关的内容如Vue路由、生命周期、API等也可以集中讲解。 需要特别注意用户提到的“事务”部分,要区分数据库事务和Spring事务管理的不同应用场景。反射在Java中的应用,比如动态代理,可以结合Spring AOP简要说明。Redis数据类型如String、List、Hash等需要列举并简要说明用途。 在生成问题时,要确保每个主要技术点都有相关问题,帮助用户深入探索。例如,关于多线程的问题可以涉及线程池配置,HashMap遍历的方法比较,或者SpringBoot配置的多环境管理。 总结来说,回答需要结构清晰,分点明确,涵盖所有提到的技术,同时生成的问题要具有针对性和实用性,引导用户进一步学习。</think>### 多种IT技术详解与使用方法 #### 1. **Java** - **核心特性**:面向对象、跨平台(JVM)、多线程(`Thread`类与`Runnable`接口)、反射(动态加载类)[^1]。 - **注解**:如`@Override`标记方法重写,`@Autowired`实现Spring依赖注入。 - **多态**:父类引用指向子类对象,例如: ```java Animal dog = new Dog(); dog.sound(); // 调用Dog类的实现 ``` #### 2. **JavaScript** - **作用**:前端交互逻辑实现,支持事件驱动和异步编程(Promise)。 - **遍历数组**: ```javascript [1,2,3].forEach(item => console.log(item)); ``` #### 3. **MySQL** - **事务**:通过`BEGIN; COMMIT; ROLLBACK;`保证ACID特性,Spring中通过`@Transactional`注解管理[^1]。 - **数据库设计**:遵循三范式,合理使用索引(如B+树结构)提升查询效率。 #### 4. **C语言** - **特点**:面向过程,指针操作直接内存,适用于系统级开发。 - **数据结构**:链表、栈(后进先出)与队列(先进先出)的实现。 #### 5. **Vue3** - **生命周期**:`setup()`替代`created`/`mounted`,组合式API提高代码复用性。 - **组件通信**:`props`父传子,`emit`子传父,`provide/inject`跨层级传递。 - **指令**:`v-if`(条件渲染,操作DOM)与`v-show`(CSS切换显示)。 #### 6. **SpringBoot** - **配置**:`application.yml`支持多环境配置(`spring.profiles.active=dev`)。 - **AOP**:通过`@Aspect`实现日志记录或事务管理,基于动态代理模式[^1]。 #### 7. **Mybatis** - **作用**:ORM框架,通过XML或注解映射SQL语句,如`@Select("SELECT * FROM user")`。 #### 8. **Redis** - **数据类型**:String(缓存)、Hash(存储对象)、List(消息队列)、Set(去重集合)。 #### 9. **Nginx** - **反向代理**:配置`proxy_pass`转发请求,实现负载均衡。 ```nginx location / { proxy_pass http://backend_server; } ``` #### 10. **Git** - **核心命令**:`git commit`提交代码,`git rebase`合并分支历史,`git cherry-pick`选择性提交。 #### 11. **其他技术** - **RocketMQ**:分布式消息队列,支持事务消息和顺序消息。 - **IDEA插件**:Lombok通过`@Data`自动生成Getter/Setter[^1]。 - **前端三件套**:HTML(结构)、CSS(样式)、JavaScript(行为)。 --- ###
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值