自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 信号量的实例

/最后一个成员通常被设置为SEM_UNDO,使得操作系统跟踪当前进程的信号量修改情况,如果进程在没有使用该信号量的情况下终止掉,那么操作系统会自动释放该进程持有的信号量。cmd通常有两个最常用的值,SETVAL,IPC_RMID,SETVAL表示把信号量初始化一个已知的值,IPC_RMID表示删除无需再使用的信号量。key的作用是一个整数值,不相关的进程可以通过他访问同一个信号量。semid是第一个函数返回的信号量描述符,类似于文件描述符。该函数的作用是创建一个新的信号量或者是获取一个信号量。

2024-07-26 19:28:57 121

原创 epoll的原理

2024-07-25 17:53:59 49

原创 select、poll、epoll的区别

1. SELECT的机理以及缺陷:1. SELECT的机理以及缺陷:poll函数实现的机理:1.在调用select函数时,第二个参数为&read_fds,这个参数实际上就是左侧图中的bitmap,总共有1024位,CPU会将该bitmap从用户态拷贝到内核态,由内核去判断是否有就绪事件的发生。2.在判断过程中,调用select函数的进程会处于阻塞状态,当客户端给服务端发来数据时,会拷贝到数据的接收队列中,当接收队列中有数据时,会唤醒相应的进程。

2024-07-25 17:10:43 443

原创 死锁----

死锁发生的条件:

2024-07-25 16:21:24 71

原创 粘包和半包

2024-07-24 21:21:04 88

原创 epoll的实现

首先在epoll_create()会创建一个file事例,通过private_data创建eventpoll实例,当增删改时,会对rbr进行操作,rdllist存储的是就绪的事件。2.epoll在epoll_wait()函数中,struct epoll_event *events参数只带出就绪事件。红黑树在比较的时候,会按照文件地址进行比较,如果地址相同则比较文件描述符,因为相同地址的文件会有不同的文件描述符。1.epoll在内核里维护了一颗红黑树,减少了在用户态和内核态之间数据的拷贝。

2024-07-24 20:41:00 119

原创 阻塞IO和非阻塞IO【多路复用】

从标准输入读上数据,通过write将数据从网卡发送到服务器接收,夫区其发来的数据通过网卡传递到接收缓冲区,客户端来读取数据。fgets和read函数默认状态下都为阻塞状态,因此当fgets处于阻塞状态时,即使read对应的接收缓冲区有数据时,也不会读到。IO阻塞:例如在socket中,接收内核缓冲区内没有数据时,read将会处于阻塞状态,阻塞的程序将会被挂起。IO复用将标准输入、输出、套接字等都看作IO的一路,无论哪一路有事件发生时都会通知应用程序取处理相应的事件。磁盘io、网络io、标准输入输出。

2024-07-24 19:53:30 284

原创 系统调用【用户态和内核态之间的转换的基本流程】

当我们从用户态转入到内核态时往往需要通过系统调用,在使用printf函数时,可能内部会调用一系列其他函数来到达对操作系统的调用接口。将printf封装这是库函数,方便我们进行使用,在printf中会有一个write()函数,此时通过write系统调用的接口进入内核态,内核态中同样也有write函数,此函数里面会出现out或者in操作。2.根据调用的方法来获取系统调用号,因为在系统调用程序时需要通过系统调用表(操作系统初始化时确定的)来决定调用具体哪一个方法。1.将用户态寄存器的地址保存到pt_regs中。

2024-07-23 21:13:40 580

原创 键盘是如何使用中断机制的?当打印一串字符到显示屏上时发生了什么???

当打印完后需要响应一次中断,之后CPU还需要将内存的打印字符再送到打印机的寄存器中,会极大浪费cpu的开销。此时加入一个DMA机制来缓解CPU的的开销,将数据移动的任务交给DMA,只需要在所有打印任务完成之后触发一次中断,最后恢复应用程序1的后续操作即可。

2024-07-23 20:25:42 411

原创 CPU与IO设备交互

程序执行时判断状态寄存器是否为busy,如果busy则等待,如果ready则将内存的数据写到exa寄存器中,再将寄存器里的值写数据寄存器里面,此时需要处理数据,所以设置状态寄存器为busy,再将数据加载到命令寄存器中,通过控制电路去打印相应的数据,当打印完成时再将设置为ready,ready时才可以往数据寄存器内写入数据,通过一个中间件来完美地控制打印机的操作。通过判断状态寄存器是否busy或者ready来决定是否将数据加载到寄存器里。问题:CPU如何知道将数据发送给哪一个寄存器?

2024-07-23 18:36:20 157

原创 操作系统的启动以及用户态和内核态

开始时通过bootloader将os程序从磁盘加载到内存中,cpu通过读取内存中的操作系统指令进行操作。应用程序通过系统调用和操作系统交互,操作系统和外设可通过两种方式进行交互,例如汇编指令和中断机制。1.计算机通电后,主板接上电,cpu执行主板上的bios指令,bios检查bootloader指令,将其加载到内存中。2.cpu执行bootloader指令,bootloader将os程序从磁盘加载到内存中。内核态:是操作系统进行时的状态,在操作系统中出现一些特权指令是被允许的。

2024-07-23 17:43:49 149

原创 操作系统的作用

2024-07-23 17:04:59 93

原创 简单的常用指令

2024-07-23 16:52:19 95

原创 一段简单程序的反汇编指令解析

mov rbp rsp:使得rbp和rsp指向相同栈内存空间,之后sub rsp 0x10,给main函数预留16字节的栈内存空间,即main函数的栈帧为16字节。mov DWORD PTR [rbp-0x8],0x2, 将0x2赋值给[rbp - 0x8]指向的内存。在下图的add函数中需要关注的点是最后将返回值存到eax里面,由eax返回到主函数,返回值传递给主函数中。这两句反汇编指令将内存的值赋值给寄存器edx,eax,在内存中的数据需要cpu内的寄存器进行运算。

2024-07-23 16:49:03 133

原创 函数调用过程

详细结束函数调用过程中汇编语句的表示的操作。

2024-07-22 19:23:09 971

原创 简单理解CPU的执行过程

首先,CPU通过pc(程序计数器)寄存器通过地址总线找到,内存地址对应的指令(将高级语言经过编译汇编链接形成的二进制指令),拿到指令,放到cpu的指令寄存器中,然后对指令寄存器的指令进行解码。再通过运算器去执行相应的操作。

2024-07-16 17:11:46 200

原创 计算机中的物理内存

无论是读地址还是写地址都必须给数据一个地址。地址引脚有十位,数据有八位。

2024-07-16 15:58:29 198

原创 C++智能指针auto_ptr(有缺陷已废弃)

在下面的操作中,ptr1的值给ptr2,那么此时ptr1的值将会为nullptr。在构造和赋值都发生了所有权的转移。调用函数的时候,接收参数的时候同样也会发生所有权的转移。auto_ptr类没有拷贝构造函数。可以看出将Right对象的资源释放掉了。

2024-06-19 00:41:42 143

原创 运行时类型识别RTTI(typeid dynamic_cast)和虚函数机制的关系

通过dynamic _cast来实现返回0代表未转换成功,返回非0代表转换成功。,否则animal无论如何都是animal类型的,那么注定不能完成转换。父类的指针类型转化为子类类型指针,超过合法操作范围,不安全。加上虚函数,animal类型可能发生改变。两种转换:编译期的转换,运行时的转化。

2024-06-15 21:34:30 190

原创 虚函数表共享和生成

每个类有不同的虚表,相同的类使用相同的虚表。模拟动态绑定的一个过程。

2024-06-15 20:59:57 143

原创 虚表-在成员函数前面加上virtual后发生了什么事情???

答:不同的虚表,倘若是同一个当子类进行覆盖的时候,父类的虚表会丢失。子类和父类是同一个虚表还是不同的虚表?子类继承的父类的虚表指针吗?

2024-06-15 20:37:52 169

原创 虚函数机制-动态绑定的应用

虚函数使得程序在运行的时候根据指针指向对象的类型来确定调用哪个函数。

2024-06-15 20:21:24 455

原创 在protobuf里定义描述rpc方法的类型

service类中包含两个虚函数即在UserServiceRpc中的两个方法,UserServiceRpc_Stub继承UserServiceRpc,此类多了RpcChannel指针,方法将会通过Rpcchannel指针调用CallMethod函数,我们将用自己写的类继承Rpcchannel,重写其中的CallMethod方法,将派生类对象传给基类指针从而调用派生类里的函数。service UserServiceRpc //在test.proto中定义。

2024-04-21 22:03:00 737

原创 RPC分布式通信框架

分布式将一个工程分为多个模块,不同模块针对不同的功能,共同组成一个完成的项目,一个模块的改变不会将整体的项目进行重新编译部署。3.在系统中,有些模块属于CPU密集型,有些属于I/O密集型,各模块对于硬件资源的需求不一样。2.任意模块的修改都将导致整个项目代码重新编译部署。2.各模块之间的访问,无法完成通信的问题如何解决。1.受限于硬件资源无法提高并发量。1.系统模块划分不是很容易。

2024-04-21 20:15:57 567

原创 protobuf的使用

3、安装所需工具:sudo apt-get install autoconf automake libtool curl make g++ unzip。1、解压压缩包:unzip protobuf-master.zip。4、自动生成configure配置文件:./autogen.sh。二、protobuf文件test.proto的实现。生成test.pb.cc test.pb.h文件。7、安装:sudo make install。5、配置环境:./configure。三、编译test.proto文件。

2024-04-21 20:04:55 190

原创 C++生产者消费者模式(条件变量和互斥锁)

条件变量的wait操作:先释放互斥锁,将其放入互斥变量的等待队列中,等待其他线程唤醒,再放入互斥锁的等待队列中去获得锁进行操作。

2024-04-15 17:05:01 295

原创 系统监测工具-tcpdump的使用

因为该同步报文段是从客户端IP地址和端口号到服务器IP地址和端口号这个传输方向上的第一个TCP报文段,所以这个序号值也就是此次通信过程中该传输方向的ISN值。并且,因为这是整个通信过程中的第一个TCP报文段,所以它没有针对对方发送来的TCP报文段的确认值(尚未收到任何对方发送来的 TCP 报文段)。因为这是一次 TCP 通信的第一个 TCP报文段,所以它针对对方的时间戳的应答为0(尚未收到对方的时间戳)。因为这是一个同步报文段,所以win值反映的是实际的接收通告窗口大小。一个简单的tcpdump抓包过程。

2024-04-07 01:58:23 574 3

原创 TCP挥手中TIME_WAIT存在的原因

新的化身可能接收到属于原来的连接的、携带应用程序数据的TCP报文段(迟到的报文段),这显然是不应该发生的。另外,因为TCP报文段的最大生存时间是MSL,所以坚持2MSL时间的TIMEWAIT状态能够确保网络上两个传输方向上尚未被接收到的、迟到的TCP报文段都已经消失(被中转路由器丢弃)。因此,一个连接的新的化身可以在2MSL时间之后安全地建立,而绝对不会接收到属于原来连接的应用程序数据,这就是TIMEWAIT状态要持续2MSL时间的原因。2.保证让迟来的 TCP报文段有足够的时间被识别并丢弃。

2024-04-06 21:35:33 260

原创 事务的隔离级别

事务隔离级别(图文详解) - 知乎 (zhihu.com)

2024-03-20 08:56:25 93

原创 epoll函数的剖析

events 参数是一个用户数组,这个数组仅仅在 epoll_wait 返回时保存内核检测到的所有就绪事件,而不像 select 和 poll 的数组参数那样既用于传入用户注册的事件,又用于输出内核检测到的就绪事件。timeout 参数指定超时时间,单位为毫秒,如果 timeout 为 0,则 epoll_wait 会立即返回,如果 timeout 为-1,则 epoll_wait 会一直阻塞,直到有事件就绪。epoll_wait()成功返回就绪的文件描述符的个数,失败返回-1,超时返回 0。

2024-03-05 17:11:57 373

原创 select函数

首先将文件描述符放到文件描述符集合当中,select去检测是否有事件发生,调用select产生返回值,返回值大于0代表有事件发生,去处理该事件,在处理事件时也可能加入新的文件描述符。maxfd 参数指定的被监听的文件描述符的总数。它通常被设置为 select 监听的所有文件描述符中的最大值+1,readfds、 writefds 和 exceptfds 参数分别指向可读、可写和异常等事件对应的文件。需要指出的是, I/O 复用虽然能同时监听多个文件描述符,但它本身是阻塞的。如果要提高并发处理的能力,可以。

2024-03-05 11:41:52 266

原创 生产者消费者模型

在生产者消费者模型中,此项目使用到了互斥锁、条件变量。例如当生产者获得锁的时候,但是进入了wait函数此时需要有四步才可以进入下一阶段。3.当消费者调用notify函数的时候,进入到互斥锁的等待队列中。4.在互斥锁等待队列中的随机获得锁。此时才可以通过wait操作。2.进入条件变量的等待队列中去。

2024-03-04 12:42:14 184

原创 1.线程池的实现机制

在处理并发问题时,倘若我们一个一个创建线程池再进行线程池的销毁,不但浪费资源还增加了上下文切换的开销。线程池主要是以空间来换取时间。项目将会实现固定线程池,缓存线程池,工作窃取线程池,计划线程池。开发环境:VS2022,Linux g++如图所示给任务队列分配在线程池里线程。线程池用到的模式是半同步、半异步模式。

2024-03-04 00:25:44 195

原创 同步和异步

所谓同步,就是在发出一个"调用"时,在没有得到结果之前,该“调用”就不返回。换句话说,就是由“调用者”主动等待这个“调用”的结果。而异步则是相反,"调用"在发出之后,这个调用就直接返回了,所以没有返回结果。同步——如果使用者在服务运行的过程中阻塞时崩溃了,当它重新启动时,将无法重新连接到正在进行的调用,所以响应丢失了。异步——如果使用者在发送了请求之后等待响应时崩溃了,当它重新启动时,可以继续等待响应,所以响应不会丢失。2. 异步,就是我调用一个功能,不需要知道该功能结果,该功能有结果后通知我(回调通知)

2024-03-04 00:05:20 197

原创 Libevent的使用及reactor模型

支持多种 I/O 多路复用技术, epoll、 poll、 dev/poll、 select 和 kqueue 等;libevent的流程可以分为三步:定义框架,注册事件,启动事件循环(epoll检测事件是否发生,发生的时候,通知子线程调用回调函数//此过程会阻塞)下图为编写的框架。事件源可以理解为我们的文件描述符,多路复用机制是我们的IO模型(select,poll,epoll),事件处理程序理解为回调函数。Reactor:事件源(描述符)、Reactor 框架、多路复用机制和事件处理程序。

2024-03-03 21:23:10 592

原创 【回溯】子集 子集||

其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。返回的解集中,子集可以按。返回该数组所有可能的子集(幂集)。1.给你一个整数数组。

2024-02-27 21:38:33 210

原创 [回溯]复原ip地址

思路:此题思路,注意使用insert和erase函数来完成回溯的过程。终止条件为"."为3个时即可进行结果的填充。在回溯时要注意因为将字符串进行了增加,所以递归时需要将+2而非+1。,用以表示一个 IP 地址,返回所有可能的。正好由四个整数(每个整数位于。之间组成,且不能含有前导。给定一个只包含数字的字符串。,这些地址可以通过在。

2024-02-27 19:31:24 122

原创 【回溯】分割回文子串

思路:此题的关键在于确定分割线,分割线即前面组合问题提到的开始下标。我们startindex到i位置的字串进行判断检验是否为回文串。结束标志为分割线到了字符串的末尾。是正着读和反着读都一样的字符串。分割成一些子串,使每个子串都是。所有可能的分割方案。

2024-02-26 22:03:29 339

原创 【回溯】组合问题||

思路:此题最重要的一个点为:通过used的符号来判断是否继续执行操作。先初始化used为false之后若是树的上下排列其中used的值会为true,而是树本层的操作的话,used的值通过回溯会返回到false,自此可以直接跳过操作。中的每个数字在每个组合中只能使用。给定一个候选人编号的集合。解集不能包含重复的组合。中所有可以使数字和为。

2024-02-26 20:33:23 127

原创 [回溯]组合总和

2 和 3 可以形成一组候选,2 + 2 + 3 = 7。注意 2 可以使用多次。如果至少一个数字的被选数量不同,则两种组合是不同的。7 也是一个候选, 7 = 7。,并以列表形式返回。中可以使数字和为目标数。对于给定的输入,保证和为。

2024-02-25 22:15:34 395

空空如也

空空如也

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

TA关注的人

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