自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(92)
  • 收藏
  • 关注

原创 【Linux】多路转接 -- epoll

struct epoll_event结构当中有两个成员,第一个成员events表示的是需要监听的事件,第二个成员data是一个联合体结构,一般选择使用该结构当中的fd,表示需要监听的文件描述符。epoll_ctl 函数用于向指定的epoll模型中注册事件,它不同于seletct()的一点就是,select在监听事件时告诉内核要监听什么类型的事件,而它是先注册要监听的事件类型。epoll的高性能,是有特定的场景的,如果场景选择不合适,epoll的性能可能适得其反。

2023-08-09 09:14:12 141

原创 【计算机网络】应用层协议 -- 安全的HTTPS协议

HTTPS工作过程中涉及到的密钥有三组第一组(非对称加密):用于校验证书是否被篡改,服务器持有私钥,客户端持有公钥。服务器在客户端请求时,返回携带签名的证书,客户端通过公钥对证书进行验证,保证证书的合法性,进而保证证书中携带的服务端公钥的权威性。第二组(非对称加密):用于协商生成对称加密的密钥,客户端收到CA证书中的公钥给随机生成的对称加密的密钥进行加密,服务器通过私钥解密获取到对称加密的密钥。第三组(对称加密):客户端和服务器后续传输的数据都通过这个对称密钥加密解密。

2023-07-27 16:44:34 2096

原创 【计算机网络】应用层协议 -- HTTP协议

比如你不小心点了某个链接,这个链接可能就是一个下载程序,当你点击之后它就会通过某种方式将程序下载到你本地,并且自动执行该程序,该程序会扫描你的浏览器当中的Cookie目录,把所有的Cookie信息通过网络的方式传送给恶意方,当恶意方拿到你的Cookie信息后就可以拷贝到它浏览器对应的Cookie目录当中,然后以你的身份访问你曾经访问过的网站。其中HTTP请求是由客户端发送的,因此HTTP请求当中表明的是客户端的HTTP版本,而HTTP响应是由服务器发送的,因此HTTP响应表明的是服务器的HTTP版本。

2023-07-26 17:08:04 1084 2

原创 【Linux】线程安全

因为该执行流第一次申请锁的时候是申请成功的,但第二次申请锁的时候,因为该锁已经被申请过了,于是申请失败,导致被挂起知道该锁被释放时才会被唤醒,但是这个锁本来就在自己手上,自己现在处于被挂起的状态根本没有机会释放锁,所以该执行流永远不会被唤醒,此时该执行流也就处于一种死锁的状态。我们在上述简易抢票系统中引入互斥量,每一个线程要进入临界区之前都必须先申请锁,只有申请到锁的线程才可以进入临界区对临界资源进行访问,并且当下出临界区的时候需要进行解锁,这样才能让其余要进入临界区的线程继续竞争锁。

2023-07-16 23:54:27 227

原创 【Linux】线程详解

在一个程序里的一个执行路线就叫做线程。更准确的定义是:线程是“一个进程内部的控制序列”一切进程都至少有一个执行线程线程在进程内部运行,本质是在进程地址空间内运行在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更轻量化透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流进程的创建伴随着进程控制块,进程地址空间以及页表的创建,虚拟地址和物理地址就是通过页表建立映射的。

2023-07-15 23:56:35 1980

原创 【Linux】进程间通信

根据以上代码,当进程A申请访问共享内存资源时,如果此时sem为1,则进程A申请资源成功,此时将sem减一,然后进程A就可以对共享内存进行一系列操作,但是在进程A访问共享内存时,若是进程B申请访问该共享内存资源,此时sem就为0了,那么此时进程B会被挂起,知道进程A访问共享内存结束后将sem加一,此时才会将进程B唤起,然后进程B再对该共享内存进行访问操作。实际上,管道是生命周期随进程的,而共享内存的生命周期是随内核的,也就是说进程虽然以及退出,但是曾经创建的共享内存不会随着进程的退出而释放。

2023-07-12 17:26:47 771

原创 【Linux】进程地址空间

操作,操作系统会了保证进程的独立性,就会在内存的另一块区域拷贝一份原有的资源,并改变页表的映射关系,然后把原来的共享数据拷贝到新的空间内,且此时父进程和子进程看到的就不是同一块资源了。大家在自己的虚拟地址内做操作,再将对应的操作映射到指定的物理地址上,从而保证进程的独立性。在运行一段时间之后,在子进程中改变全局变量a的值,但是父进程打印a的值却没改变,但是父子进程中变量a的地址又是相同的。Linux中存在一个写时拷贝的机制,在父进程创建子进程之后,子进程继承父进程的资源,此时父子进程看到的是同一块资源。

2023-07-02 11:17:08 214

原创 【Linux】进程状态

在CPU执行进程时,可能进程要去访问外设,但是外设资源此时被占用着,它要去等待外设就绪,而CPU此时也不再调度这个进程了,这时候这个进程不再处于运行状态,而是处于阻塞状态!**在CPU执行进程时,通过找到进程的PCB,从而找到进程的代码和数据,从而去执行这个进程的方法。这是Linux操作系统中进程状态的定义,通过注释可以看出,运行状态本质是就是一个整数,在进程的PCB中,这个整数是几,就代表这个进程是什么状态。提起操作系统中的进程状态,你脑海里可能有几种概念,比如运行,阻塞,挂起,等待,停止,死亡等。

2023-06-29 11:31:28 314

原创 【C++】非类型模板参数

1,浮点数,字符串,以及自定义类型不能作为非类型模板参数(其实非类型模板参数的设计就是解决数组大小这种问题的)非类型形参:用一个常量作为类(函数)模板的一个参数,在类(模板)中可将该参数作为一个常量来使用。类型形参:出现在模板参数列表中,跟在class或者typename后面的参数类型名称。非类型模板参数是一个常量,在显示实例化时传入变量会报错。2,非类型模板参数必须在编译时就能确认结果。模板形参分为类型形参和非类型形参。

2024-07-31 12:24:45 370

原创 【C++】模板的特化

比如,在比较两个数的大小时,如果传入两个变量的指针,那么可能会得到错误的结果。此时我们的期望是比较指针所指向的内容的值,那么就需要模板的特化了。通常情况下,使用模板可以实现一些与类型无关的代码,但是有一些类型需要特殊处理,否则可能会得到一些错误的结果。此时,就需要对模板进行特化。即在原模板的基础上,针对特殊类型进行特殊化的实现方式。全特化是将类模板参数列表中所有参数都进行特化。模板的特化又分为函数模板特化和类模板特化。

2024-07-31 12:24:40 1016

原创 【C++】继承

继承机制是面向对象程序设计使代码可以复用最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,产生新的类,称为派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前所接触的复用都是函数复用,继承是类设计层次的复用。继承基类成员访问方式的变化基类private成员在派生类中不管以什么方式继承都是不可见的如果要基类成员在类外不能被访问,但是在派生类中可以被访问,就定义为protected。

2024-07-31 12:24:35 1103 2

原创 【C++】多态

多态是不同继承关系的对象,去调用同一函数,产生了不同的行为。比如,Student和Soilder继承了Person。Person对象买票全价,Student对象买票半价,Soilder对象买票优先。那么在继承中构成多态需要两个条件必须通过基类的指针或者引用调用虚函数被调用的函数必须是虚函数,且派生类需对基类的虚函数进行重写。

2024-07-31 12:24:27 997 1

原创 【C++11新特性】右值引用和移动语义

为了更好地解决问题,这里需要借助一个深拷贝的类,下面模拟实现了一个简化版的string类。右值引用和万能引用的区别就是,右值引用需要的是确定的类型,而万能引用是根据传入实参的类型进行推导,如果传入的实参是一个左值,那么这里的形参t就是左值引用,如果传入的实参是一个右值,那么这里的形参t就是右值引用。移动赋值是一个赋值运算符重载函数,该函数的参数是右值引用类型的,移动赋值也是将传入右值的资源窃取过来,占为己有,这样就避免了深拷贝,所以它叫移动赋值,就是窃取别人的资源来为自己赋值的意思。

2024-07-31 12:24:05 966

原创 【C++11新特性】lambda表达式

的方式捕捉变量时,编译器也不一定会把父作用域所有的变量捕获进来,编译器可能只会对lambda表达式中用到的变量进行捕获,没有必要把用不到的变量也捕获进来,这个主要看编译器的具体实现。这样一来,调用lambda表达式时就不用传入参数了,但实际我们只需要用到变量a和变量b,没有必要把父作用域中的所有变量都进行捕捉,因此也可以只对父作用域中的a、b变量进行捕捉。但由于这里是传值捕捉,lambda函数中对a和b的修改不会影响外面的a、b变量,与函数的传值传参是一个道理,因此这种方法无法完成两个数的交换。

2024-07-31 12:23:59 1219

原创 【C++11新特性】可变参数模板

模板参数Args前面有省略号,代表它是一个可变参数模板,我们把带省略号的参数称为参数包,参数包里面可以包含0到N(N>=0)个模板参数,而args则是一个函数形参参数包。模板参数包Args和函数形参参数包args的名字可以任意指定。现在调用ShowList函数时就可以传入任意多个参数了,并且这些参数可以是不同类型的。我们可以在函数模板中通过sizeof计算参数包中参数的个数但是我们无法直接获取参数包中的每个参数,只能通过展开参数包的方式获取,这是使用可变参数模板的一个主要特点,也是最大的难点。

2024-07-31 12:23:53 781

原创 【C++】继承

继承的概念继承机制是面向对象程序设计使代码可以复用的重要手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称为派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,而继承便是类设计层次的复用。例如,以下代码中Student类和Teacher类就继承了Person类。// 父类public:protected:string _name = "张三";// 子类protected:int _stuid;

2024-07-31 12:23:47 1034

原创 【C++11新特性】function包装器

function包装器是一种函数包装器,也叫做适配器。它可以对可调用对象进行包装,C++中的function本质就是一个类模板。Ret:被包装的可调用对象的返回值类型。Args…:被包装的课调用对象的形参类型。包装示例function包装器可以对可调用对象进行包装,包括函数指针(函数名)、仿函数(函数对象)、lambda表达式、类的成员函数。public:class Pluspublic:int main()// 1、包装函数指针(函数名)

2024-07-31 12:23:41 742

原创 【C++】文件IO流

C++流是指信息从外部输入设备(如键盘)向计算机内部(如内存)输入和从计算机内部向外部输出设备(如显示器)输出的过程。“流”是流动的意思,是物质从一处向另一处流动的过程,是对一种有序连续且有方向性的数据的抽象描述。注意: 可以在定义文件流对象的同时指定将要打开的文件名,以及文件的打开方式。使用 >> 和

2024-07-31 12:23:22 503

原创 【Linux】多路转接 -- select函数

多路转接也叫多路复用,是一种用于管理多个IO通道的技术。它能实现同时监听和处理多个IO事件,而不是为每个IO通道创建单独的线程或者进程,多路转接允许在单个进程或线程中同时处理多个IO操作,从而提高程序的性能和效率。本篇文章介绍的select函数,就用于select系统调用的多路转接技术。select函数是系统提供的一个多路转接接口。IO = 等待就绪 + 数据拷贝,而select是只负责等。参数说明:参数timeout的取值:返回值说明:select调用失败,错误码可能被设置为:fd_set 结构与 si

2024-07-31 12:20:16 1567

原创 【MySQL】内置函数

对于多字节字符来说,不同编码中一个字符所占的字节个数是不同的,比如utf8中一个字符占用3个字节,而gbk中一个字符占用2个字节。strcmp函数用于逐字符按照ASCII码比较两个字符串的大小,两个字符串大小相等返回0,前者大返回1,后者大返回-1。现有如下成绩表,要求以“XXX的语文是XX分,数学是XX分,英语是XX分”的格式显示成绩表中的信息。substring函数用于从字符串的指定位置开始,向后截取指定个数的字符。left函数用于从字符串的左边开始,向后截取指定个数的字符。

2023-10-30 19:51:34 225

原创 【MySQL】表的增删查改

通常情况下不建议使用 * 进行全列查询,因为被查询到的数据需要通过网络从MySQL服务器传输到本主机,查询的列越多也就意味着需要传输的数据量越大,此外,进行全列查询还可能会影响到索引的使用。在select的column列表中指明要查询的列为姓名、数学成绩、英语成绩和语文成绩,在order by子句中指明依次按照数学成绩排降序、英语成绩排升序和语文成绩排升序。再向表中插入一些数据,在插入数据时不指明自增长字段的值,这时会发现插入数据对应的自增长id值是在之前的基础上继续增长的。

2023-10-30 19:50:49 240

原创 Reactor网络模式

可以在当前服务器的基础上接入线程池,当recver回调读取完数据并完成报文的切割和反序列化之后,就可以将其构建成一个任务然后放到线程池的任务队列中,然后服务器就可以继续进行事件派发,而不需要将事件耗费到业务处理上面,而放到任务队列当中的任务,则由线程池当中的若干个线程进行处理。下一次Dispatcher在进行事件派发的时候就会帮我们关注该套接字的写事件,当写事件就绪就会执行该套接字对应的EventItem结构中的写回调方法,进而将outbuffer中的响应数据发送给客户端。

2023-10-09 16:30:43 428

原创 【MySQL】数据类型

而如果是无符号float类型得到取值范围,实际就是把对应有符号float类型中的负数部分全部拿走了,因此float(4,2)的取值范围为0 ~ 99.99,实际可插入的范围为0 ~ 99.994。

2023-10-07 16:06:58 924

原创 【MySQL】表的约束

真正约束字段的是数据类型,但是数据类型约束很单一,需要一些额外的约束,来更好地保证数据的合法性,从业务逻辑角度保证数据的正确性。

2023-09-26 20:37:01 240

原创 【MySQL】表的基本操作

本篇博客介绍表的DDL操作。

2023-08-17 08:54:03 83

原创 【MySQL】数据库基础

数据库是按照数据结构来组织、存储和管理数据的仓库,是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。存储数据用文件就可以了,为什么还要弄个数据库呢?文件的安全性问题:数据误操作之后无法进行回退文件不利于数据查询和管理:没有将存储的数据以某种数据结构组织起来文件不利于存储海量数据:数据量越大用户操作数据的成本越高文件在程序中控制不方便:数据的控制需要用户自己来完成总之,文件虽然确实提供了数据的存储功能,但是文件并没有提供非常好的数据管理能力。

2023-08-15 09:05:59 396

原创 【MySQL】数据库的基本操作

表恢复之前需要先选中一个数据库,表明需要将表恢复到哪一个数据库中去,为了防止恢复出来的表与该数据库中已有的表的表明恢复,一般在恢复表时会选择创建一个空的数据库,然后在该数据库中进行表的恢复。使用不同的校验规则操作数据库中的数据可能会得到不同的结果,比如utf8_general_ci校验规则在比对数据时是不区分大小写的,而utf8_bin校验规则在对比数据时则是区分大小写的。如果没有对MySQL的配置文件进行过修改,那么默认的编码格式是utf8,默认的校验规则是utf8_general_ci。

2023-08-12 21:46:57 191

原创 【Linux】多路转接 -- poll函数

poll函数原型如下:

2023-08-07 22:32:50 1083

原创 【Linux】五种IO模型

其实,这个钓鱼场景中的各个事务都能与IO当中的相关概念对应起来,比如这里钓鱼的河对应就是内核,这里的每一个人都说进程或者线程,鱼竿对应的就是文件描述符或套接字,装鱼的桶对应的就是用户缓冲区。任何IO的过程,都包含等和拷贝这两个步骤,在实际的应用场景中“等”消耗的时间远比“拷贝”消耗的时间多,因此要让IO变得高效,就要尽可能减少“等”的时间。需要注意的是,这里问的是他们的钓鱼效率是否一样,而不是问他们整体谁做的事更多,如果说整体做事情的量的话,那一定是王五做的最多,李四次之,张三最少。

2023-08-04 15:46:50 427

原创 【计算机网络】应用层协议 -- DNS协议

域名是用来识别主机名称和主机所属的组织机构的一种分层结构的名称,例如。com:一级域名,表示这是一个工商企业域名。同级的还有.net(网络供应商)和.org(开源组织或非盈利组织)等。baidu:二级域名,一般对应的就是公司名。www:只是一种习惯用法。

2023-08-03 22:19:44 1699

原创 【计算机网络】传输层协议 -- TCP协议

从文章的长度也可以看出,TCP协议是非常复杂的,它之所以这么复杂,就是因为它既要保持可靠性,同时又要尽可能地提高性能。检验和序列号确认应答超时重传连接管理流量控制拥塞控制滑动窗口快速重传延迟应答捎带应答TCP的这些机制有些是通过协议来体现的,有些是通过代码逻辑实现的。TCP定时器此外,TCP当中还设置了各种定时器重传定时器:为了控制丢失的报文段或者丢弃的报文段,也就是对报文段确认的等待时间。

2023-07-30 22:03:30 3236

原创 【计算机网络】传输层协议 -- UDP协议

应用层交给UDP多长的报文,UDP就按原样发送,既不会拆分,也不会合并,这就叫做面向数据报。比如用UDP传输100个字节的数据:如果发送端调用一次sendto,发送100字节数据,那么接收端也必须调用一次recvfrom,接收100个字节数据。而不能循环调用10次recvfrom,每次接收10个字节数据。

2023-07-28 14:59:01 1449

原创 【计算机网络】简易TCP网络小程序

我们将TCP服务器封装成一个类,当我们定义出一个服务器对象后需要马上对服务器进行初始化,而初始化TCP服务器要做的第一件事就是创建套接字。TCP服务器在调用socket函数创建套接字时,参数设置如下:如果创建套接字后获得的文件描述符是小于0的,说明套接字创建失败,此时也就没必要进行后续操作了,直接终止程序即可。说明一下:实际TCP服务器创建套接字的做法与UDP服务器是一样的,只不过TCP服务器需要的是流式服务,而UDP服务器需要的是用户数据报服务。套接字创建完毕之后我们实际只是在系统层面上打开了一个文件,

2023-07-24 23:24:02 1738

原创 【计算机网络】简易UDP网络小程序

在进行绑定的时候需要将IP地址和端口号告诉对应的网络文件,此时就可以改变网络文件当中文件操作函数的指向,将对应的操作函数改为对应网卡的操作方法,此时读数据和写数据对应的操作对象就是网卡了,所以绑定实际上就是将文件和网络关联起来。理论上是这样的,但是我用的是云服务器,云服务器的IP地址是由对应的云厂商提供的,这个IP地址并不一定是真正的公网IP,这个IP地址是不能直接被绑定的,如果要让外网访问,我们需要将IP地址绑定为。构造客户端时需要传入对应服务器的IP地址和端口号,我们这里也可以引入命令行参数。

2023-07-22 21:41:23 640

原创 【计算机网络】socket编程基础

当数据在传输层进行封装时,就会添加上对应源端口号和目的端口号的信息,在网络层又会添加上对应源IP地址和目的IP地址,这样一来,通过源端口号和源IP地址就能在网络上标识发送数据的进程,通过目的端口号和目的ID地址就可以在网络上标识接收数据的进程,这就实现了跨网络的进程间通信。同样的,UDP协议虽然是一种不可靠的传输协议,但这一定意味着UDP协议在底层不需要做过多的工作,因此UDP协议底层的实现一定比TCP协议要简单的多,UDP协议虽然不可靠,但是它能把数据快速地发给对方,虽然数据在传输的过程中可能会出错。

2023-07-21 15:34:32 1062

原创 【计算机网络】网络基础

也就是说,虽然客户端和服务器可能使用的是不同种类的操作系统,但每个系统实现网络协议栈的方法包括各种细节都是一样的,因此双方对数据进行封包和解包操作都是一样的。

2023-07-20 17:37:40 393

原创 【Linux】线程池

当我们去处理任务时,创建线程去进行处理,然后释放线程资源,在下次再有任务时,再创建线程,这样反反复复效率是比较低的。我们可以发现这五个线程在处理时会呈现一定的顺序性,因为主线程是每秒Push一个任务,这五个线程只会有一个线程获取到该任务,其他线程都会在等待队列中进行等待,当该线程处理完任务后就会因为任务队列为空而排到等待队列的最后,当主线程再次Push一个任务后唤醒等待队列首部的一个线程,这个线程处理完任务后又会排到等待队列的最后,因此这五个队列在处理任务时会呈现一定的顺序性。:一种线程使用模式。

2023-07-19 22:46:11 126

原创 【Linux】生产者消费者模型 -- RingQueue

在主函数中创建一个生产者线程和一个消费者线程,生产者线程不断将数据放入环形队列,消费者线程不断从环形队列里取出数据进行消费。现在我们用信号量来描述环形队列中的空间资源(blank_sem)和数据资源(data_sem),在我们初识化信号量时给它们设置的初始值是不同的;在我们自己所写的代码中,我们虽然只让生产者一秒生产一次,而没让消费者的消费速度受限制,但是它们最终的步调是一致的,这正是信号量的作用所在。信号量的初识值为1,说明信号量所描述的临界资源只有一份,此时信号量的作用基本等价于互斥锁。

2023-07-18 15:03:47 327

原创 【Linux】生产者消费者模型 -- BlockQueue

生产者和消费者彼此之间不直接通讯,而通过这个容器来通讯,所以生产者生产完数据之后不用等待消费者处理,直接将生产的数据放到这个容器中,消费者也不用找生产者要数据,而是直接从这个容器里取数据,这个容器就相当于一个缓冲区,平衡了生产者和消费者的处理能力,这个容器实际上就是用来给生产者和消费者解耦的。其中,所有的生产者和消费者都会竞争式地申请锁,因此生产者和生产者,消费者和生产者,生产者和消费者之间都存在互斥关系。生产者和生产者,消费者和消费者,生产者和消费者,它们之间为什么存在互斥关系?

2023-07-17 16:35:04 256

原创 【Linux】进程信号

当涉及到Linux操作系统中的进程通信和控制时,信号(signal)是一个重要概念,它通常用于在进程之间传递通知和控制信息。信号可以被认为是一种异步通信机制,它允许一个进程向另一个进程发送一个特定的信号,并且接收进程可以采取适当的行动来相应该信号。进程可以发送信号给其他进程,也可以发送信号给自己。

2023-07-14 17:06:06 1506

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除