自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 网络编程:socket编程与两个简单的UdpServer练习

所有服务器本质上都是输入是输出的问题,所以,我们无需重新编写网络模块,将翻译的功能部分添加进去。而是,可以通过函数对象与回调函数的方式,不让网络通信模块与业务模块强耦合,采用模块与模块调用嵌合的方式,提高代码的健壮性。客户端中,我们这里将消息的接收与发送分别使用两个bash命令行窗口,便于可以更清晰的观察收到的信息。并且将消息的接收与发送操作分离,使得客户端即使不进行消息发送也可以接收其他主机发送的消息。,将标准错误重定向到指定的bash命令行文件,从而达成收到信息的分离显示。

2025-11-29 09:32:40 721

原创 网络编程:初识socket编程

socket编程是一种类似于之前学习过的Systerm V通信标准的全新的通信方案,且其不仅仅可以用于网络通信,同时也可以用于本地通信与网络管理。其中,网络通信部分是基于TCP/IP协议而实现设计的具体方案,虽然,其有多个使用方向,但,都是使用同一套接口实现的。

2025-11-21 09:59:27 1012

原创 网络编程:网络基础(1)

一台计算机中,主板与各种通信线路相连,硬件电路本质上也是一种网络,将计算机中的各个设备连接起来,使用单机协议进行通信与协同工作,共同配合实现一台计算机的功能。因此,通信过程中所需要传递的数据量越小越好,通信的次数越少越好。不同的主机之间想要进行通信都必须要遵守同一套通信标准,传输层与网络层的相关功能程序因其对应的协议标准确定、变动不大,因此,其都直接被各自计算机中的操作系统实现。只是,与常规的软件分层设计不同的是,网络的分层结构中不单单只有纯软件行为了,其中也有了一些物理设备上的操作,乃至于纯物理操作。

2025-11-06 11:57:48 574

原创 Linux学习:线程相关重要概念补充

读者写者模型默认都为读者优先的模型,即读线程与写线程竞争共享资源时,读者优先访问。因为,此模型应用的场景为读者众多,写者较少,是需要进行大量高频的读操作的,写操作的频率不用太高。相似的,读者写者模型也是有两种角色,一个数据交易场所。但不同的是,其中读者、写者的三种关系与消费者生产者模型中有区别。死锁是指多个线程之间互相申请对方的锁又不释放自身持有的锁,导致双方都阻塞挂起从而处于一种永久彼此等待的特殊状态。加读锁时,写线程申请写锁会被阻塞,其他读线程申请读锁则可以正常申请。读锁、写锁都用此接口来解锁。

2025-09-21 20:48:59 672

原创 Linux学习:线程池的简单实现

日志信息与格式[年-月-日 时:分:秒(日志产生的时间)][日志等级][进程pid][产生日志所在的文件][日志打印所在的行数]具体的日志信息日志等级标识日志信息的等级,共分为Info(普通信息)Debug(调试信息)Warning(警告)Error(错误)Fatal(致命)Unknown(未知)日志的输出方向定义一个bool类型全局变量gIsSave,用于标识日志信息的输出方向。当值为false时,直接向显示器上输出打印,当值为true时,向指定记录文件中输出。

2025-09-21 14:15:31 1076

原创 Linux学习:基于环形队列的生产者消费者模型

信号量不仅仅其申请与释放操作都是互斥的,而且本身还同时具有计数的作用。因此,在功能上,其就相当于是互斥锁与条件变量的结合,但其又只需要一条操作语句就可以实现互斥锁与条件变量的配合效果。,分别作为生产者资源与消费者资源的计数器,每次在生产者、消费者线程访问环形队列之前,都要预先申请对应的信号量资源。生产者生产数据存入队列,消费者消费数据从队列中获取,此处使用方案1中的环形队列设计方式。记录队列中新数据插入位置的下标,起始设置为0。记录队列中存储数据的个数,每次插入数据后进行。的位置相同,因此,需要以。

2025-09-11 20:40:25 693

原创 Linux学习:基于阻塞队列的生产者消费者模型

生产者消费者模型是一种经典的并发编程的设计模式。其由三部分组成分别为生产者消费者与共享资源缓冲区。生产任务、数据的线程或进程处理任务、数据的线程或进程任务与数据的暂存区,生产者向其中存储任务与数据,消费者从中获取任务与数据。简单来说,共享资源缓冲区,是一段临时保存数据的内存空间,一般使用某种数据结构对象充当(阻塞队列)角色关系生产者 vs 生产者互斥 || 同步(互斥,可能同步)消费者 vs 消费者互斥 || 同步(互斥,可能同步)生产者 vs 消费者互斥 && 同步。

2025-09-03 21:15:13 1025

原创 Linux学习:线程同步与条件变量

  在线程之间保持互斥的前提下,程序可以正常运行不出错。但单单的互斥可能会导致出现进程饥饿的不合理情况。当有的线程调度优先级很高,竞争锁的能力很强时,就会导致其一直申请访问到临界资源,而其他线程无法访问到临界资源,从而造成进程饥饿的问题。  操作系统中针对上述线程饥饿的问题,提出了相应的名为同步解决策略。  Linux操作系统中对于线程同步的实现方式之一,为条件变量。接下来就让我们认识什么是条件变量,条件变量如何使用,以及如何通过条件变量做到线程同步。  pthread原生线程库中定义有一个数据类型,用

2025-09-02 16:28:25 1065

原创 Linux学习:线程互斥

因此,也就很大概率可能会导致出现上图中,线程被切换,执行流被打断从而导致后续的多个线程访问的数据不一致,最终造成严重的错误bug。在线程执行临界区中的代码时,也可能会被切换走,但即使是被切换,其他线程也无法申请到锁,所以也就无法访问临界资源。锁是pthread原生线程库中实现的一个数据类型,因此,在使用锁之前需要先定义出锁类型的变量,即创建一个锁。其他部分代码不变,定义一把全局锁并初始化,而后,在任务函数中访问临界区的代码部分之前上锁,对临界区代码访问完成后进行解锁。的方式来具体实现线程间的互斥。

2025-09-01 15:31:57 1005

原创 Linux学习:简单模拟实现C++中的线程类

类型的参数,让其使用此参数去调用任务函数。从而达到让线程能够执行指定任务函数的效果,此种设计方式让任务函数的定义更加灵活自由,更便于使用。此处设计中,只能使用静态成员函数将任务函数进行包装,这是因为普通的成员函数固定会有一个隐藏参数,指向自己的。而线程函数的传参此处设计中,并不是直接进行传参,而是使用。在线程类的设计中,真正负责创建并启动线程的成员函数是。将任务函数进行封装,然后传参给。

2025-08-31 12:56:05 353

原创 Linux学习:线程函数的使用与理解

同理,线程函数的返回值也可以采取类似于传参时的思路,使得返回的信息更加多样化。这样的传参与返回方式大大提高了多线程编程的实用性。因为传递的函数参数和返回值类型不确定,所以,都将其设置为。

2025-08-30 11:52:50 344

原创 Linux学习:线程控制

虽然所有线程共用一个地址空间,所有线程都可以通过取地址的方式访问地址空间中的任意一处资源,但一般情况线程之间都不会通过此种方式去访问其他线程内的资源。主线程在创建局部变量与开辟函数栈帧时,都是直接在地址空间中的栈区进行。但,其他线程并不和主线程共用此栈区,每一个其他线程都会在共享区中创建出一块属于自己的独立栈空间来自己使用。

2025-08-29 15:17:11 1071

原创 Linux学习:线程的概念与理解

每行代码都有自己的地址,不同的线程执行的函数是不同的,即它们拥有的转换而来代码块地址资源也是不同的,线程在执行时只能通过自己的函数得到一批代码块的虚拟地址,使用这些虚拟地址也只能以此查看页表的一部分。操作系统使用链表的方式将线程管理起来,又因为线程又只是进程的一个执行分支,其所使用的也是进程的资源,所以也需要标识自己所属的进程。因为线程只是进程中的一个执行流,其所需要使用的资源也是进程中的资源,所以,创建线程时就不需要再如进程般去进行,诸如,创建程序地址空间、建立映射、加载程序等操作。

2025-08-28 09:28:38 643

原创 Linux学习:信号的处理

可以说,是操作系统让这些进程得以运行起来,而操作系统本身也可以视为一个进程,那么,操作系统如何得知应该何时执行什么任务,操作系统的运行是由谁推动起来的呢?但,这样的处理条件详细思考之下,不难发现,若是进程中没有去调用系统调用接口来访问内核资源,那么,进程从内核态切换到用户态的情况也就不会出现,进程会始终保持用户态。既然子进程运行结束时,会向父进程发出一个。CPU中会有一个寄存器用来存放标识进程状态的信息,其低两位bit位的值为0时,代表进程当前是内核态,当低两位bit为的值为3时,代表进程当前是用户态。

2025-08-26 15:41:34 1182

原创 Linux学习:信号的保存

信号的阻塞与忽略并不是一种行为,对信号进行阻塞,进程是无法识别到有对应的信号到了,所以也就不会做出响应处理。而信号的忽略,则是进程已经识别到了信号,但对信号采用了忽略这一处理方式,所以,表现出的现象就是进程什么都没有做。进程运行时,可以循环打印自己的pending表,当表bit位为1时,表示着进程收到了信号,但信号并没有被处理,这代表信号成功被阻塞。此类型为操作系统提供的位图类型,创建一个此类型变量修改其中内容并配合相应的系统调用接口就可以达到对block表的修改,即控制进程阻塞哪些信号。

2025-08-23 20:25:02 606

原创 Linux学习:信号的概念与产生方式

  过马路时,斑马线旁的红绿灯,红灯停绿灯行;学校里,每当上课时就嗡嗡作响的上课铃;工作日,早晨固定响起的手机闹钟。这些都是信号,而这些信号中往往都蕴含着一些信息。红灯亮起,表示着斑马线就不能继续通行;上课铃响,表示着要回到教室座位做好上课的准备;闹钟响起,表示着需要起床开始新一天的生活。可见,信号是信息传递的载体,当这些蕴含着信息的信号出现时,我们就要做出相对应的行为动作。  Linux操作系统中也存在并设计了信号的概念与相关功能,上述实例中的我们,就类比于操作系统的进程。而操作系统中的信号其功能作用与

2025-08-21 22:21:44 892

原创 Linux学习:Systerm V版本的进程间通信(2)

所以,解决多执行流并发访问同一份共享资源时出现数据不一致的问题,是十分重要的,也是必须的。而当信号量的初始值不为1时,也就说把一份资源分割成多份小型资源使用,我们再使用信号量限制进行访问的进程数量之后,如何合理的给每一个进行访问操作的进程合理分配资源,具体就需要程序员去控制实现。电影院中,演播厅与座位数量都是有限的,因此,在售票时,售出电影票的总数量也是有限的。上图中,Systerm V版本通信的各个记录资源属性的数据结构,并不是真正的操作系统内核中用于描述与管理相关资源的内核数据结构,

2025-08-19 20:07:08 817

原创 Linux学习:实现简单的共享内存通信

共享内存虽然是所有通信手段中速度最快的,可是,其不具备同步机制。这就可能导致数据不一致问题,也会让读端进行很多无效读取。通信前提,不同进程看到同一份资源。用于更好的打印观察key值。负责命名管道的创建与销毁。,快速批量修改字符串。

2025-08-18 17:25:06 284

原创 Linux学习:Systerm V版本的进程间通信(1)

因此,一个消息队列中会有不同进程发送的数据块,为了能够让进程区分出自己需要的数据块,每个数据块头部都会存储相应的标识类型。Systerm V的通信方式是一种操作系统的内核通信模块,在底层实现中有操作系统与内核资源的参与。指定获取哪个类型的数据块,传入宏控制读取数据块的模式。完成,一次性写入或读取数据的长度,既可以通过将void*类型指针强转成不同类型的指针控制,又可以通过对应的函数接口实现。随着通信技术的不断发展,出现了更多更丰富的通信手段,这些通信方式的功能与接口也越来越标准化。

2025-08-17 21:04:46 971

原创 C++进阶:IO流

当采用文本读写的方式对文件进行存储或写入时,自定义类型的读写是一个仍待解决的问题。C++中流的插入提取操作本质上,是通过库中定义的默认operator<<operator>>操作来进行支持的。因此,实际上我们也可以通过自己实现重载自定义类型的operator<<operator>>函数,来使得自定义类型可以支持文本方式的读写。class Datepublic:{}//支持多组输入// 假设输入_year为0时结束elseprivate:int _year;int _month;

2025-08-16 13:28:22 636

原创 C++进阶:类型转换

  C语言中的类型转换分为隐式类型转换与显示类型转换,类型转换只能发生在具有关联性的类型之间,无关联性的类型之间无法发生类型转换。隐式类型转换规则:  隐式类型转换不需要我们显示去操控,而是当操作符合条件时就会自动发生。在赋值操作时,类型转换是向被赋值对象的类型进行转换。除此之外,在表达式中,运算或比较等情况下参与的数据必须要转为同一类型后才能继续进行后续操作。这里数据类型转换的规则为int大小以下的类型char、short转为运算时都必须转换为int类型,而int类型在于除此之外的其他类型进行运算时,会

2025-08-15 14:52:51 777

原创 C++进阶:特殊类

创建一个类其不能够被拷贝,不能使用其拷贝构造其他对象,不能用其为其他对象赋值,C++库中就存在着这样的类,诸如,istream、ostream、unique_ptr。因为此模式下设计的类整个程序的全局范围内只允许有一份资源,所以,此类的构造函数与赋值重载需要使用delete禁止其生成。懒汉模式的第一种设计模式也是采用全局的静态成员变量的方式去存储资源,但与饿汉模式不同的是,此时的静态成员变量为指针类型。私有化析构设计的只能堆上开辟的类,其对象不能够自动释放自己的资源,但new申请出的资源还是需要释放的。

2025-08-14 22:12:00 923

原创 C++进阶:智能指针

其除了具备智能指针管理资源与指针操作的功能外,对智能指针的拷贝也做了相关的实现,其设计思路为拷贝后,将指针转移,将原有指针悬空。weak_ptr只做链接功能,因为weak_ptr与shared_ptr不是一个类型的智能指针,weak_ptr想要从shared_ptr获取资源只有两个方式,一是被声明为友元,二是为shared_ptr添加get接口,get接口必须使用const修饰this指针。自定义一个双向链表的节点,链表的每个节点都是动态开辟而出的,这里我们采用智能指针的方式去定义与管理。

2025-08-14 13:00:39 1249

原创 C++进阶:异常

虽然异常可以是任何类型,但在多人项目中,为了更好的合作与项目编写。对于异常往往是会有一套项目组内自定义的异常体系的,通常会先确定一个异常基类,里面包含着最基础的必须的异常信息,后续根据异常来源的不同,继承异常基类并添加新的异常信息。下面是一套常用于服务器开发的自定义异常体系逻辑。(服务器开发一般会分为网络层开发、缓存层开发、数据库层开发)服务器开发的自定义异常体系自定义异常使用的简单模拟场景。

2025-08-13 12:06:49 871

原创 C++进阶:C++11(2)

/计算参数包中模板参数个数声明方式,函数模板参数处表示声明了一个模板参数包,这个模板参数包内可能包含0到N任意个模板参数。自定义list中对接口服用了emplace接口,emplace接口到调用成员变量构造前都要确保将参数包传递下去。可变模板参数包通过配合万能引用与完美转发一直传递到调用相应的成员变量构造处,而后成员变量会使用参数包直接进行构造。自定义list与Date类配合验证push_back与接口的实现效果。当list存储节点类型是深拷贝,存在移动构造时,可变模板参数包就会做出相应的匹配。

2025-08-11 23:22:50 1241

原创 C++进阶:C++11(1)

如果返回值只是内置类型,或是不大的自定义类型,这样的操作倒也无关痛痒,可是当返回值很大时,这样的操作就是一个影响效率的大问题了。右值引用的属性为左值,const右值引用的属性为const左值,当我们采用函数模板的引用折叠后,虽然可以匹配各种参数的引用类型,不再用写多个冗余的函数,但却无法保持右值的原本属性,在函数内部调用时无法匹配相对应类型的接口。右值可以被const修饰的左值引用去引用,当没有右值引用的接口时,右值会默认匹配左值引用的接口,但当右值引用被定义时,右值则只会配置右值引用的接口。

2025-08-10 15:19:29 777

原创 Linux学习:自实现一个简单的进程池

自定义管道类型需要包含,管道所链接子进程的"r"端文件fd、子进程的pid、子进程的名称(格式为channel-num)。再创建分别返回这三个成员变量的成员函数,让程序在合适的时候调用这些存储在Channel类型的有用信息。//进程池:子进程数量,与子进程通信的管道public:{}//创建子进程//具体实现见标题3...//杀死并回收所有子进程。

2025-08-08 11:35:02 253

原创 Linux学习:进程通信(管道)

什么是进程间的通信两个进程之间可以直接进行"数据"的直接传递吗,这显然是不行的,显然会违背进程本身的独立性。可是,进程在创建子进程的过程中,子进程不是会继承父进程内核数据结构中的各种信息吗,父进程正可以通过这一方式实现对子进程数据的传递。虽然父子进程数据与代码共享,会写时拷贝,但它们之间也是独立的(拥有独立的内核数据结构)。单次数据的传递不能被称之为通信,而且也没有实际的应用价值,一个进程能把自己的数据交给另一个进程,反之亦然,多次可重复双向的数据交换我们才称之为进程间的通信。进程间通信的价值和意义。

2025-03-26 16:09:42 809

原创 Linux学习:动、静态库

回顾库是一种编程语言用来屏蔽底层差异的方法手段,库中会提供各种常用的基础方法,来实现对系统调用的封装。Linux操作系统一般会默认安装动态库,Linux云服务器默认不安装静态库(C标准库),因此,当需要使用使用静态库时需要进行下载。在Linux操作系统下,动态库文件后缀.so,静态库文件后缀为.a。我们使用gcc/g++编译器对.c/cpp文件进行编译时,默认调用动态库采用动态链接,要使用静态链接时指令中需要添加-static选项。动态链接指令:gcc -o 可执行程序名 代码文件。

2025-03-12 20:41:11 1216

原创 Linux学习:文件系统

Linux操作系统下一切皆文件,因此,程序我们也可以将其理解为一种文件,进程是被加载进入内存调度运行的程序,所以之前对于进程的学习我们也可以理解为是针对被打开文件的学习。可是,操作系统中并非所有的文件都是被打开的,反而,大部分的文件都是没有被打开的状态,这些大量的未打开的文件都存储在磁盘上,因此,未被打开的文件我们也可以称之为磁盘文件。

2025-03-09 00:18:07 1114

原创 Linux学习:C语言缓冲区与文件接口简单模拟实现

/刷新模式宏定义1<<11<<21<<3//刷新模式宏定义 # define NONE_FLUSH(1 << 1) # define LINE_FLUSH(1 << 2) # define FULL_FLUSH(1 << 3) //FILE类型 # define SIZE 4096 typedef struct _myFILE {//输入缓冲区 char outbuffer [ SIZE ];//输出缓冲区 int cap;//容量 int pos;

2024-12-19 14:55:03 315

原创 C语言:函数栈帧的创建与销毁

不同的开发环境对于函数栈帧的创建与销毁,实现细节上是不同的,但思路上大体相同,我们接下来对函数栈帧的刨析都是基于vs2013这一个集成开发环境的结果。观察所用示例代码,如下:1int z = 0;z = x + y;return z;int b = 20;int c = 0;return 0;接下来我们会配合编译生成的汇编代码,监视窗口,内存窗口等工具,在调试模式下,来具体观察函数栈帧创建于销毁的每一步骤。

2024-11-11 14:41:17 1132 1

原创 C++进阶:哈希(2)位图与布隆过滤器

【代码】C++进阶:哈希(2)位图与布隆过滤器。

2024-05-15 13:57:02 1286

原创 C++进阶:哈希(1)

在C++库中,除开map与set这两个关联式容器外,还存在着另外两个此类容器,unordered_set,unordered_map。unordered中文释义为无序的,这也正是这一对容器使用时的表征特点,这一对容器分别对应set与map,即K模型与KV模型的存储数据结点。那么,除开使用迭代器遍历时,其内存储数据无序外,这一对容器与map与set容器有何不同,为什么要在已有map与set的情况下,再向库中加入这一对乍看功能冗余且劣于原本map与set的容器呢?我们来看下面的一组对照试验。

2024-05-13 22:27:08 1212

原创 C++进阶:map与set简单自实现

/结点结构Red,BlackT _kv;,_kv(kv),_col(Red){}//树结构public://查找//插入private:KeyOfT con;

2024-05-09 19:34:37 606

原创 C++进阶:红黑树

抽象子树结构cde中每条路径中有两个黑色结点。抽象子树cde中每条路径都包含一个黑色结点。抽象子树abcde为空。

2024-04-28 23:40:45 1139

原创 C++进阶:AVL树

4. 根据抽象模型的实际场景数分析。

2024-04-27 14:38:59 932

原创 C++进阶:map与set容器的使用

【代码】C++进阶:map与set容器的使用。

2024-04-24 14:42:06 1245

原创 Linux学习:文件描述符fd与基础IO

从上面我们新学习到的Linux系统文件相关系统调用接口,可以看出其对文件进行的一系列操作都是通过open接口的返回值fd来实现的,通过fd来找到对应的文件进行写入,读取,关闭等操作。fd是一个整形数据,其被称作文件描述符,可是这一个整形数据是如何标识表明不同文件的呢,打开不同文件时其的值又有什么不同吗?close(fd1);close(fd2);close(fd3);close(fd4);close(fd5);return 0;

2024-04-23 16:55:04 1269

原创 C++进阶:搜索树

【代码】C++进阶:搜索树。

2024-04-20 22:54:21 2230

空空如也

空空如也

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

TA关注的人

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