首页
题库
公司真题
专项练习
面试题库
在线编程
面试
面试经验
AI 模拟面试
简历
求职
学习
基础学习课
实战项目课
求职辅导课
专栏&文章
竞赛
我要招人
发布职位
发布职位、邀约牛人
更多企业解决方案
AI面试、笔试、校招、雇品
HR免费试用AI面试
最新面试提效必备
登录
/
注册
在写论文的西西
中华女子学院 C++
发布于陕西
关注
已关注
取消关注
记
@wrdoct:
C++——WebServer服务器项目(2)
3.多线程 (1)多线程共享虚拟地址空间,其中栈空间和.text(代码段)被每个线程瓜分(不共享),其他都是共享的资源。线程id、error变量、线程特有数据等也不共享。 (2) //创建一个子线程int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);//终止一个线程,在哪个线程中调用,就表示终止哪个线程void pthread_exit(void *retval);//获取当前的线程的线程IDpthread_t pthread_self(void);//比较两个线程ID是否相等int pthread_equal(pthread_t t1, pthread_t t2);//和一个已经终止的线程进行连接(回收线程)int pthread_join(pthread_t thread, void **retval);//分离一个线程。被分离的线程在终止的时候,会自动释放资源返回给系统int pthread_detach(pthread_t thread);//取消线程(让线程终止)int pthread_cancel(pthread_t thread); (3)线程同步/线程安全:原因:相较于进程需要通过各种IPC来共享信息进行通信,线程可以很方便的使用全局变量来共享信息。【注】临界区是指访问某一共享资源的代码片段,并且这段代码的执行应为原子操作,不会被打断。一次仅允许一个线程使用的共享资源。 概念:当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作,其他线程才能对该内存地址进行操作,而其他线程则处于等待状态。 线程同步的实现一般有下面5种:互斥量,读写锁,条件变量,自旋锁,屏障。 //初始化互斥量int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);//释放互斥量的资源int pthread_mutex_destroy(pthread_mutex_t *mutex); //加锁,阻塞的,如果有一个线程加锁了,那么其他的线程只能阻塞等待int pthread_mutex_lock(pthread_mutex_t *mutex); //尝试加锁,如果加锁失败,不会阻塞,会直接返回。int pthread_mutex_trylock(pthread_mutex_t *mutex);//解锁 - int pthread_mutex_unlock(pthread_mutex_t *mutex); (4)死锁:忘记释放锁;多次加锁;多线程多锁,抢占锁资源。 产生死锁的四个必要条件:互斥条件:一个资源每次只能被一个进程使用。请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。不剥夺条件: 进程已获得的资源,在末使用完之前,不能强行剥夺。循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。存在一个进程等待序列{P1,P2,…,Pn},其中P1等待P2所占有的某一资源,P2等待P3所占有的某一资源,……,而Pn等待P1所占有的的某一资源,形成一个进程循环等待环。 解决死锁的四个方式:鸵鸟算法(直接忽略该问题)。检测死锁并且恢复(检测与解除策略)。仔细地对资源进行动态分配,以避免死锁(避免策略)。通过破除死锁四个必要条件之一,来防止死锁产生(预防策略) (5)生产者与消费者模型:条件变量: //初始化一个条件变量int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);//释放一个条件变量int pthread_cond_destroy(pthread_cond_t *cond);//等待,调用了该函数,线程会阻塞。int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);//等待多长时间,调用了这个函数,线程会阻塞,直到指定的时间结束。int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);//唤醒一个或者多个等待的线程int pthread_cond_signal(pthread_cond_t *cond);//唤醒所有的等待的线程int pthread_cond_broadcast(pthread_cond_t *cond); 信号量:互斥锁+条件变量 //初始化信号量int sem_init(sem_t *sem, int pshared, unsigned int value);//释放资源int sem_destroy(sem_t *sem);//对信号量加锁,调用一次对信号量的值-1,如果值为0,就阻塞int sem_wait(sem_t *sem);//对信号量解锁,调用一次对信号量的值+1int sem_post(sem_t *sem); (6)读写锁:读多写少时使用读写锁,提高效率。 有线程在读,其他线程也可读,不能写;有线程在写,其他线程不能读,不能写;写是独占的,优先级高。 4.网络编程 (1)网卡功能:数据的封装与解封装;链路管理;数据编码与译码。 (2)MAC地址:48位(6个字节)。IP地址:32位(4个字节)。 (3)特殊地址: 当前主机:0.0.0.0当前子网的广播地址:255.255.255.255回路测试:127.0.0.1~127.255.255.255 (4)子网掩码:将IP地址分为网络地址和主机地址两部分。【注】网络号:IP与子网掩码&主机号:子网掩码取反与IP& 子网数:首先根据第一个字节判断是哪个类:<=127:A——255.0.0.0<=191:B——255.255.0.0<223:C——255.255.255.0看子网掩码比默认的多几个1,就是2的几次方个子网数;主机数:后面的0有几个,就是2的几次方主机数。 (5)端口:网络通信中应用程序对外的一个接口,2个字节。 周知端口:0~1023注册端口:1024~49151动态端口:49152~65535 (6)网络模型;TCP/IP协议族;UDP、TCP、IP、以太网帧、ARP的报文头部结构。 (7)上层使用下层提供的服务,通过封装实现。从下往上进行解析:分用。 (8)socket套接字:一套通信的接口。socket地址——结构体。 (9)字节序:大端(网络字节序):整数的高位字节在内存的低地址处。小端:整数的高位字节在内存的高地址处。 (10)TCP:可靠、面向连接、字节流、传输层。三次握手目的:为了让双方都知道可以互相通信。TCP的状态转换。 (11)服务端的端口复用:防止服务器重启时之前绑定的端口还未释放;程序突然退出而系统没有释放端口。 (12)通信并发:多进程/多线程解决。 一个父进程,多个子进程;父进程负责等待,并接收客户端连接;子进程完成通信,每接收一个客户端连接,就创建一个子进程用于通信。 缺点:耗费资源。 (13)I/O多路复用技术:使程序能同时监听多个文件描述符,提高程序性能。分为阻塞(BIO)和非阻塞(NIO)。select、poll、epoll。 具体参考这篇答应我,这次搞懂 I/O 多路复用! epoll的工作模式:LT水平触发、ET边缘触发(减少了epoll事件被重复触发的次数)。 5.补充(阻塞/非阻塞、同步/异步、HTTP、服务器编程、有限状态机、正则、压力测试等) (1)阻塞/非阻塞、同步/异步(网络I/O):【注】磁盘IO(I:从磁盘读入内存;O:从内存写入磁盘)。网络IO。 在处理 IO 的时候,阻塞和非阻塞都是同步 IO,只有使用了特殊的 API 才是异步 IO。 一个典型的网络IO接口调用,分为两个阶段,分别是 “数据就绪” 和 “数据读写”,数据就绪阶段分为阻塞和非阻塞,表现得结果就是,阻塞当前线程或是直接返回。数据读写阶段分为同步和异步。 同步表示A向B请求调用一个网络IO接口时(或者调用某个业务逻辑API接口时),数据的读写都是 由请求方A自己来完成的(不管是阻塞还是非阻塞)——效率低,编程简单,消耗用户时间。异步表示A向B请求调用一个网络IO接口时 (或者调用某个业务逻辑API接口时),向B传入请求的事件(fd)以及事件发生时通知的方式(sigio),A就可以处理其它逻辑了,当B监听到事件处理完成后,会用事先约定好的通知方式,通知A处理结果——效率高,编程复杂,不消耗用户时间。(2)Unix/Linux的五种IO模型: 1、阻塞 blocking:等待数据(中间不能做其他事);拷贝到用户区。2、非阻塞 non-blocking(NIO):等待数据(中间能做其他事);拷贝到用户区;返回-1带上EAGAIN;线程不会挂起,系统调用次数多,影响性能。3、IO复用(IO multiplexing):一个进程检测多个IO操作;select、poll、epoll。4、信号驱动(signal-driven):内核在第一个阶段是异步,在第二个阶段是同步。5、异步: ===========================================================================(3)HTTP协议: 1.客户端连接到Web服务器;2.发送HTTP请求;3.服务器接受请求并返回HTTP响应;4.释放TCP连接;5.客户端浏览器解析HTML内容。 (4)HTTP请求报文和响应报文格式。 (5)HTTP请求方法: GET:显示请求。POST:提交数据。HEAD:请求资源。PUT:上传资源。 (6)HTTP状态码: 1xx:请求已被接收,正在处理2xx:请求接收成功3xx:重定向4xx:请求错误5xx:服务器错误 【注】200 OK; 404 Not Found;403 Forbidden; 500 Internal Server Error。 =========================================================================== (7)服务器编程的基本框架:| 模块 | 功能 ||--|--|| I/O 处理单元 |处理客户连接,读写网络数据/接收发送数据||逻辑单元 | 业务进程或线程/解析数据|| 网络存储单元 | 数据库、文件或缓存 || 请求队列 | 各单元之间的通信方式 | (8)两种高效的事件处理模式:Reactor 和 Proactor ,同步 I/O 模型通常用于实现 Reactor 模式,异步 I/O 模型通常用于实现 Proactor 模式。 Reactor和Proactor模式的主要区别就是 真正的读取和写入操作是由谁来完成的。Reactor来了事件操作系统通知应用进程,让应用进程来处理;Proactor来了事件操作系统来处理,处理完再通知应用进程。 Reactor:(实现简单)主线程(I/O处理单元)只负责监听fd是否有事件发生,有就通知工作线程(逻辑单元),将socket事件(可读可写)放入请求队列,交给工作线程处理。除此之外主线程不做其他工作。Proactor:(性能更高)将所有I/O操作都交给主线程和内核来处理(进行读写),工作线程仅仅负责业务逻辑(解析HTTP请求,在封装成响应数据发回去)。 工作流程:1、Reactor:(同步I/O)主线程往 epoll 内核事件表中注册(epoll_ctl) socket 上的读就绪事件;主线程调用 epoll_wait 等待 socket 上有数据可读;当 socket 上有数据可读时, epoll_wait 通知主线程。主线程则将 socket 可读事件放入请求队列;睡眠在请求队列上的某个工作线程被唤醒,它从 socket 读取数据,并处理客户请求,然后往epoll内核事件表中注册(epoll_ctl)该 socket 上的写就绪事件;当主线程调用 epoll_wait 等待 socket 可写;当 socket 可写时,epoll_wait 通知主线程。主线程将 socket 可写事件放入请求队列;睡眠在请求队列上的某个工作线程被唤醒,它往 socket 上写入服务器处理客户请求的结果。 2、Proactor:(异步I/O 模型)(同步I/O模型)见Linux高并发服务器开发 【注】服务器处理三类事件:I/O事件、信号事件、定时事件。 (9)线程池:由服务器预先创建的一组子线程;线程池中的线程数量应该和 CPU 数量差不多;线程池中的所有子线程都运行着相同的代码。 实质:1、空间换时间,浪费服务器的硬件资源,换取运行效率。2、池是一组资源的集合,这组资源在服务器启动之初就被完全创建好并初始化,这称为静态资源。3、当服务器进入正式运行阶段,开始处理客户请求的时候,如果它需要相关的资源,可以直接从池中 获取,无需动态分配。4、当服务器处理完一个客户连接后,可以把相关的资源放回池中,无需执行系统调用释放资源。 实现线程池的步骤:(队列)1.设置一个生产者消费者队列,作为临界资源;2.初始化几个线程,并让其运行起来,加锁去队列里取任务运行;3.当任务队列为空时,所有线程阻塞;4.当生产者队列来了一个任务后,先对队列加锁,把任务挂到队列上,然后使用条件变量去通知阻塞中的一个线程来处理。 =========================================================================== (10)有限状态机:有的应用层协议头部包含数据包类型字段,每种类型可以映射为逻辑单元的一种执行状态,服务器可以根据它来编写相应的处理逻辑。是逻辑单元内部的一种高效编程方法。可使用枚举+switch语句==>解析头还是解析体。 (11)正则: (12)异步日志:开启一个子线程,从队列里读,开始写日志。同步日志:在主线程里写日志。(要等待,效率慢,浪费性能) (13)EPOLLONESHOT事件:即使可以使用 ET 模式,一个 socket 上的某个事件还是可能被触发多次。这在并发程序中就会引起一个问题。比如一个线程在读取完某个 socket 上的数据后开始处理这些数据,而在数据的处理过程中该socket 上又有新数据可读( EPOLLIN 再次被触发),此时另外一个线程被唤醒来读取这些新的数据。于是就出现了两个线程同时操作一个 socket 的局面。一个 socket 连接在任一时刻都只被一个线程处理,可以使用 epoll 的 EPOLLONESHOT 事件实现。 对于注册了 EPOLLONESHOT 事件的文件描述符,操作系统最多触发其上注册的一个可读、可写或者异常事件,且只触发一次,除非我们使用 epoll_ctl 函数重置该文件描述符上注册的 EPOLLONESHOT 事件。这样,当一个线程在处理某个 socket 时,其他线程是不可能有机会操作该 socket 的。但反过来思考,注册了 EPOLLONESHOT 事件的 socket 一旦被某个线程处理完毕, 该线程就应该立即重置这个socket 上的 EPOLLONESHOT 事件,以确保这个 socket 下一次可读时,其 EPOLLIN 事件能被触发,进而让其他工作线程有机会继续处理这个 socket 。 (14)服务器的压力测试:展示服务器的两项内容: 每秒钟响应请求数和每秒钟传输数据量。基本原理:Webbench 首先 fork 出多个子进程,每个子进程都循环做 web 访问测试。子进程把访问的结果通过pipe 告诉父进程,父进程做最终的结果统计。 webbench -c 1000 -t 30 http://192.168.160.128:10000/index.html 参数: -c 表示客户端数 -t 表示时间 源码地址(学习更新中) webserver 参考: 【操作系统】进程的切换与控制·到底有啥关系?[项目] Linux高并发服务器答应我,这次搞懂 I/O 多路复用!Linux高并发服务器开发
点赞 27
评论 3
全部评论
推荐
最新
楼层
暂无评论,快来抢首评~
相关推荐
09-16 18:15
门头沟学院 大数据开发工程师
银行秋招
存一下准备挨个投一下
小小:
银行秋招真题,欢迎大家来刷:牛客 -> 题库 -> 国央企笔试真题 。https://www.nowcoder.com/exam/company?questionJobId=195&subTabName=written_page
点赞
评论
收藏
分享
09-16 11:29
成都大学 游戏策划
秋招第一面是字节,简直了
投递的隔天就收到了hr的电话,没想到这辈子简历能过节子的筛选过程中就是疯狂深挖简历+问这么做的原因 但因为准备的不充分很多问题都只能磕磕巴巴地答出一点点...不过能面我都很意外了
我的秋招日记
点赞
评论
收藏
分享
08-05 18:59
京东_零售-平台产品与研发中心_前端开发(实习员工)
用友你要干啥😡
三分钟走完流程这一块😰
扉川川:
查看图片
投递用友等公司10个岗位
点赞
评论
收藏
分享
09-04 14:00
已编辑
门头沟学院 Java
秋招连大厂HR筛都过不了的简历长啥样?
BG: 双非硕 + 学院本秋招投递情况: 阿里系(简历挂)、美团(这周做二笔)、小米(笔试写完,筛选中)、快手(简历挂)、滴滴(笔试挂)、小红书(笔试挂)、马上消费(简历挂)、鹰角网络(简历挂)、蔚来(简历挂)… 还有部分大厂(京东、百度、腾讯、科大讯飞、网易雷火…)和中厂在泡池子中投递时间: 8.20开始~至今进面情况: 无一家进面自我剖析: 学历硬伤 + 笔试差 (要多刷题了)下面附上一张简历,请各位牛友帮忙指点指点~引流:字节 阿里 腾讯 美团 百度 京东 拼多多 滴滴 快手 科大讯飞
凝孑哒哒:
项目经历,不要光写工作内容,要加一些在这个项目中学习了什么有什么成长,比如实现什么设计模式,学会什么设计思想,还有就是明确你在这个项目中的具体职责,最终对项目有什么成果
投递快手等公司10个岗位
点赞
评论
收藏
分享
09-15 14:29
上海大学 运营
腾讯pcg热点运营面经
某个明星的负面新闻突然在全网爆发,短时间内评论区出现了大量负面情绪。作为热点运营,你觉得除了快速推送新闻本身,我们还需要关注哪些潜在的风险?你会如何建议团队处理这种局面,以维护平台的健康生态? 你认为腾讯新闻在内容呈现上有什么独特之处?如果让你为某个热门话题设计一个互动形式,你会如何提升用户的参与感和讨论度? 如何判断一个信息是否具备成为“爆点”的潜力? 一些新闻在发布后可能会引起争议,出现反转的情况。你认为作为热点运营,在这种情况下最重要的是什么?你会如何处理这些可能出现的不确定性,并给用户提供负责任的信息? 评估一个热点新闻推送的效果你觉得哪些数据指标是最重要的?你会如何根据这些数据来判断...
查看10道真题和解析
点赞
评论
收藏
分享
评论
点赞成功,聊一聊 >
点赞
收藏
分享
评论
提到的真题
返回内容
全站热榜
更多
1
...
🎉创作红榜第2期丨7篇内容解决你的“求职/职场/成长困惑”!
9904
2
...
阿里菜鸟-JAVA研发一二面(已挂)
3795
3
...
这,就是你想看的爽文嘛?
3436
4
...
字节没戏了分享一波面经吧
2620
美团秋招进展
热聊中
5
...
招银网络科技一面
2119
6
...
携程 后端 线下面
2064
7
...
【26秋招】我是如何从男模上岸大厂程序员----上岸前的苦苦挣扎(2)
1938
8
...
宣讲会真有用吗
1892
9
...
滴滴池子这么大嘛
1880
10
...
嵌入式面试真的很难吗
1713
创作者周榜
更多
正在热议
更多
#
从顶到拉给所有面过的公司评分
#
43430次浏览
286人参与
#
产品薪资爆料
#
130806次浏览
834人参与
#
宣讲会你有哪些意向不到的收获
#
5498次浏览
36人参与
#
水滴求职进展汇总
#
6087次浏览
29人参与
#
聊聊这家公司值得去吗
#
580014次浏览
3814人参与
#
签约/解约注意事项
#
722700次浏览
4101人参与
#
你怎么评价今年的春招?
#
130782次浏览
1369人参与
#
为了求职,我做过的疯狂伪装
#
20354次浏览
449人参与
#
机械制造岗投递时间线
#
28000次浏览
372人参与
#
晒晒你的中秋福利
#
18608次浏览
134人参与
#
工作压力大怎么缓解
#
107670次浏览
1070人参与
#
bilibili求职进展汇总
#
99934次浏览
863人参与
#
十一假期一定要干的事
#
18036次浏览
143人参与
#
职场破冰,你们都聊什么?
#
11323次浏览
93人参与
#
你的国庆怎么过
#
27275次浏览
250人参与
#
小厂实习有必要去吗
#
56333次浏览
284人参与
#
你面试被问到过哪些不会的问题?
#
37668次浏览
1053人参与
#
秋招的嫡长offer
#
52386次浏览
443人参与
#
机械笔面试考察这些知识点
#
12471次浏览
96人参与
#
电网笔面经互助
#
47989次浏览
435人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务