(2)
(3)线程同步/线程安全:
原因:相较于进程需要通过各种来共享信息进行通信,线程可以很方便的使用全局变量来共享信息。
【注】临界区是指访问某一共享资源的代码片段,并且这段代码的执行应为原子操作,不会被打断。一次仅允许一个线程使用的共享资源。
概念:当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作,其他线程才能对该内存地址进行操作,而其他线程则处于等待状态。
线程同步的实现一般有下面5种:互斥量,读写锁,条件变量,自旋锁,屏障。
(4)死锁:忘记释放锁;多次加锁;多线程多锁,抢占锁资源。
产生死锁的四个必要条件:
互斥条件:一个资源每次只能被一个进程使用。
请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
不剥夺条件: 进程已获得的资源,在末使用完之前,不能强行剥夺。
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。存在一个进程等待序列{P1,P2,…,Pn},其中P1等待P2所占有的某一资源,P2等待P3所占有的某一资源,……,而Pn等待P1所占有的的某一资源,形成一个进程循环等待环。
解决死锁的四个方式:
鸵鸟算法(直接忽略该问题)。
检测死锁并且恢复(检测与解除策略)。
仔细地对资源进行动态分配,以避免死锁(避免策略)。
通过破除死锁四个必要条件之一,来防止死锁产生(预防策略)
信号量:互斥锁+条件变量
(6)读写锁:
读多写少时使用读写锁,提高效率。
(1)网卡功能:数据的封装与解封装;链路管理;数据编码与译码。
(3)特殊地址:
(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个字节。
(6)网络模型;TCP/IP协议族;UDP、TCP、IP、以太网帧、ARP的报文头部结构。
(7)上层使用下层提供的服务,通过封装实现。
从下往上进行解析:分用。
(9)字节序:
大端(网络字节序):整数的高位字节在内存的低地址处。
小端:整数的高位字节在内存的高地址处。
(10)TCP:可靠、面向连接、字节流、传输层。
三次握手目的:为了让双方都知道可以互相通信。
TCP的状态转换。
(11)服务端的端口复用:防止服务器重启时之前绑定的端口还未释放;程序突然退出而系统没有释放端口。
(12)通信并发:多进程/多线程解决。
缺点:耗费资源。
(13)I/O多路复用技术:使程序能同时监听多个文件描述符,提高程序性能。分为阻塞()和非阻塞()。
、、。
具体参考这篇答应我,这次搞懂 I/O 多路复用!
epoll的工作模式:LT水平触发、ET边缘触发(减少了epoll事件被重复触发的次数)。
在处理 IO 的时候,阻塞和非阻塞都是同步 IO,只有使用了特殊的 API 才是异步 IO。
一个典型的网络IO接口调用,分为两个阶段,分别是 “数据就绪” 和 “数据读写”,数据就绪阶段分为阻塞和非阻塞,表现得结果就是,阻塞当前线程或是直接返回。数据读写阶段分为同步和异步。
同步表示A向B请求调用一个网络IO接口时(或者调用某个业务逻辑API接口时),数据的读写都是 由请求方A自己来完成的(不管是阻塞还是非阻塞)——效率低,编程简单,消耗用户时间。
异步表示A向B请求调用一个网络IO接口时 (或者调用某个业务逻辑API接口时),向B传入请求的事件(fd)以及事件发生时通知的方式(sigio),A就可以处理其它逻辑了,当B监听到事件处理完成后,会用事先约定好的通知方式,通知A处理结果——效率高,编程复杂,不消耗用户时间。
(2)Unix/Linux的五种IO模型:
(4)HTTP请求报文和响应报文格式。
(5)HTTP请求方法:
(6)HTTP状态码:
【注】200 OK; 404 Not Found;403 Forbidden; 500 Internal Server Error。
===========================================================================
(7)服务器编程的基本框架:
| 模块 | 功能 |
|--|--|
| I/O 处理单元 |处理客户连接,读写网络数据/接收发送数据|
|逻辑单元 | 业务进程或线程/解析数据|
| 网络存储单元 | 数据库、文件或缓存 |
| 请求队列 | 各单元之间的通信方式 |
(8)两种高效的事件处理模式:
和 ,同步 I/O 模型通常用于实现 模式,异步 I/O 模型通常用于实现 模式。
和模式的主要区别就是 真正的读取和写入操作是由谁来完成的。
来了事件操作系统通知应用进程,让应用进程来处理;
来了事件操作系统来处理,处理完再通知应用进程。
工作流程:
1、Reactor:(同步I/O)
主线程往 内核事件表中注册() 上的读就绪事件;
主线程调用 等待 上有数据可读;
当 上有数据可读时, 通知主线程。主线程则将 可读事件放入请求队列;
睡眠在请求队列上的某个工作线程被唤醒,它从 读取数据,并处理客户请求,
然后往内核事件表中注册()该 上的写就绪事件;
当主线程调用 等待 可写;
当 可写时, 通知主线程。主线程将 可写事件放入请求队列;
睡眠在请求队列上的某个工作线程被唤醒,它往 上写入服务器处理客户请求的结果。
2、Proactor:
(异步I/O 模型)(同步I/O模型)
见Linux高并发服务器开发
【注】服务器处理三类事件:I/O事件、信号事件、定时事件。
(9)线程池:由服务器预先创建的一组子线程;线程池中的线程数量应该和 CPU 数量差不多;线程池中的所有子线程都运行着相同的代码。
实质:
1、空间换时间,浪费服务器的硬件资源,换取运行效率。
2、池是一组资源的集合,这组资源在服务器启动之初就被完全创建好并初始化,这称为静态资源。
3、当服务器进入正式运行阶段,开始处理客户请求的时候,如果它需要相关的资源,可以直接从池中 获取,无需动态分配。
4、当服务器处理完一个客户连接后,可以把相关的资源放回池中,无需执行系统调用释放资源。
===========================================================================
(10)有限状态机:有的应用层协议头部包含数据包类型字段,每种类型可以映射为逻辑单元的一种执行状态,服务器可以根据它来编写相应的处理逻辑。
是逻辑单元内部的一种高效编程方法。可使用枚举+switch语句==>解析头还是解析体。
(11)正则:
(12)异步日志:开启一个子线程,从队列里读,开始写日志。
同步日志:在主线程里写日志。(要等待,效率慢,浪费性能)
(13)事件:
即使可以使用 ET 模式,一个 socket 上的某个事件还是可能被触发多次。这在并发程序中就会引起一个问题。比如一个线程在读取完某个 socket 上的数据后开始处理这些数据,而在数据的处理过程中该socket 上又有新数据可读( EPOLLIN 再次被触发),此时另外一个线程被唤醒来读取这些新的数据。
于是就出现了两个线程同时操作一个 socket 的局面。一个 socket 连接在任一时刻都只被一个线程处理,可以使用 epoll 的 事件实现。
对于注册了 事件的文件描述符,操作系统最多触发其上注册的一个可读、可写或者异常事件,且只触发一次,除非我们使用 函数重置该文件描述符上注册的 事件。这样,当一个线程在处理某个 socket 时,其他线程是不可能有机会操作该 socket 的。
但反过来思考,注册了 事件的 socket 一旦被某个线程处理完毕, 该线程就应该立即重置这个socket 上的 事件,以确保这个 socket 下一次可读时,其 事件能被触发,进而让其他工作线程有机会继续处理这个 socket 。
(14)服务器的压力测试:
展示服务器的两项内容: 每秒钟响应请求数和每秒钟传输数据量。
基本原理:
首先 fork 出多个子进程,每个子进程都循环做 web 访问测试。子进程把访问的结果通过pipe 告诉父进程,父进程做最终的结果统计。
webserver
参考:
到此这篇c++ 条件变量性能(c++ 条件语句)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!【操作系统】进程的切换与控制·到底有啥关系?
[项目] Linux高并发服务器
答应我,这次搞懂 I/O 多路复用!
Linux高并发服务器开发
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/cjjbc/64837.html