- 博客(41)
- 收藏
- 关注
原创 服务器守护进程化
守护进程是一个没有终端控制的进程,它通常在系统启动时启动,独立于任何用户会话(session),并且在后台持续运行。:每个登录的用户会话都有一个会话ID(Session ID),一个会话可以有多个进程组(Process Group),而每个进程组中的进程共享同一个控制终端。系统调用来脱离当前会话及其控制终端,成为一个新的会话的首进程。:会话中的进程通常共享进程组,而进程组的控制由会话首进程管理。:守护进程首先会创建一个子进程,父进程退出,子进程继续执行,这样可以让守护进程避免与任何用户会话或终端直接交互。
2024-12-08 22:29:44
915
原创 TCP客户端服务器端通信(线程池版)
在网络编程中,TCP和UDP是两种常见的传输协议,它们之间最大的不同之一在于连接的管理方式。为了更好地理解这个区别,我们可以用一个生动的比喻来说明。假设你在一家餐馆工作,其中张三负责把客人带到座位上,而李四和王五是服务员,他们负责为客人点菜和服务。张三的角色类似于TCP连接中的。他的工作是确保当客户到达时,他们能够被快速、有效地分配给一个合适的服务员。在TCP协议中,监听套接字(就像张三)是独特的:它负责创建监听端口,通过这个端口,服务器可以接收到请求。
2024-12-08 20:23:15
1072
原创 linux和windows之间UDP通信的实现
sudo firewall-cmd --permanent --zone=public --add-port=8989/udp#永久的添加8080号端口。去掉--permanent则表示临时添加该端口。两者不能互相通信,服务器收不到客户端的消息。第一张图片为服务器,第二章为客户端运行结果。
2024-12-04 14:52:57
591
原创 指针数组、数组指针与函数指针
1、定义:数组指针是一个指针变量,它指向的是一个数组。在内存中,数组是连续存储的一块内存空间,数组指针存储的是数组首元素的地址。通过数组指针可以访问数组中的元素,并且可以进行指针运算来遍历数组。在这个例子中,定义了一个数组指针ptr,它可以指向一个包含 5 个整数的数组。ptr = &arr语句将ptr指向arr数组。然后通过(*ptr)[i]来访问数组中的元素,这里的*ptr相当于arr(*ptr)[i]就相当于arr[i]。
2024-11-28 15:23:29
574
原创 UDP客户端服务器通信
1、网络协议中的下三层主要解决的是,数据安全可靠得发送到远端机器2、用户使用应用层软件,完成数据的发送和接收,先把软件启动起来,那就是进程,因此网络通信的本质就是进程间的通信。
2024-11-28 15:22:08
1373
原创 跨网络传输
ip地址,尤其是目的ip一般不会改变,mac地址,出局域网之后,源和目的都要丢弃,让路由重新封装。例子,我现在想从辽宁到云南,当我走到山西,下一站我又想去陕西,因此有两套地址①从哪来到哪去--一直不变(ip地址)②上一站从哪来,下一站到哪里去--一直变化,变化的依据是“我要去哪里”(MAC地址)故事:网络专业的学生,导员在教学楼5楼,打电话叫你送达B栋5楼,但是你不知道在哪,但在A和B之间有两栋楼,每个楼的三层小楼都有一个保安,可以问保安。传输层:数据段、数据报;2、数据包转发的过程。
2024-11-27 15:22:05
259
原创 网络基础上
发送方需要解决的问题: 接收方需要解决的问题:1、怎么保证数据能准取的到达下一个设备?数据链路层2、一个数据在转发的时候如何定位主机?网络层 ip3、长距离转发的过程中数据丢失怎么办?传输层4、如何处理发来的数据?----应用层 http ftp smtp因此在每一层都要把每一层的问题解决,每层都要有自己的协议。
2024-11-26 22:20:10
450
原创 线程池的实现与应用
一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。
2024-11-21 20:54:21
478
原创 深入解析信号量:定义与环形队列生产消费模型剖析
信号量本质是计数器,用来描述临界资源中资源数量的多少!比如电影院,大家抢不同的位置,就可以一起看电影,那么共享资源内部被拆成多份,只要线程数不要超过座位数。就可以保证多线程并发访问临界资源。保证PV操作原子性,这把计数器的本质就是临界资源的数量。把资源是否就绪放在临界区之外。只要进来就一定有。申请信号量时,就已经间接的做判断了。
2024-11-21 14:36:03
682
原创 生产者和消费者模型
生产者和消费者模型是高效的,生产者在生产,消费者正在进行加工处理数据反之。一个访问临界区,一个正在访问非临界区。用户、网络等,生产者获取数据也是需要时间的!上面传递的都是整数,可不可以放对象 ,任务,一个线程给另外一个线程指派任务。321原则(3种关系、2种角色、1个交易场所-特定结构的内存空间)生产者生产的是一个任务 多生产-多消费。三、实现基于阻塞队列的生产者消费者模型。2.生产者vs消费者:互斥、同步。1.生产者vs生产者:互斥。3.消费者vs消费者:互斥。2、生产和消费进行解耦。
2024-11-21 09:56:00
250
原创 进程与多线程
一个进程可以包含多个线程,这些线程共享进程的地址空间和资源,如代码段、数据段和打开的文件等。例如,在一个网络浏览器进程中,可能有一个线程负责接收用户输入(如输入网址),一个线程负责从服务器下载网页数据,还有一个线程负责渲染页面,这些线程共同完成浏览器的功能。例如,当你打开一个文本编辑器,操作系统就会为这个文本编辑器创建一个进程,这个进程有它自己的内存空间来存储正在编辑的文本内容、程序的代码以及各种运行时的数据。一个线程可以等待某个条件变量满足,而另一个线程可以在条件满足时唤醒等待该条件变量的线程。
2024-11-19 22:19:14
632
1
原创 编写动态库
4.在/etc/ld.so.conf.d建立自己的动态库路径的配置文件,然后重新ldconfig即可。1.拷贝到系统默认的库路径 /lib64 或者/usr/lib64/2.在系统默认的库路径/lib64 /usr/lib64下建立软连接。3.将动态库的路径添加到LD_LIBRARY_PATH中。实际情况,最常用的是第一种!但是直接执行会出现以下问题。很显然没有找到动态库。
2024-07-02 22:14:54
278
原创 Linux环境变量
环境变量是一种动态的、可在操作系统级别设置和修改的值,它们在整个系统会话或进程中可用。这些变量通常用来存储配置信息、路径、系统状态等,对于Shell脚本、应用程序和用户会话都具有重要意义。
2024-06-21 09:43:51
348
1
原创 轻松入门Linux命令行(一)
ls是Linux中最常用的命令之一,用于列出目录中的文件和子目录。ls执行上述命令后,终端会列出当前目录下的所有文件和子目录。如果想要查看更详细的信息(如文件权限、所有者、大小等),可以使用-lls -l通过本文的介绍,相信大家对Linux的基本指令有了初步的了解。虽然Linux的命令行界面可能看起来有些复杂,但只要我们掌握了基本的指令和用法,就能够轻松地进行文件和目录管理、权限设置、网络配置等操作。
2024-05-28 17:33:20
456
原创 优先级队列
不是传统的队列,先进先出,而是让优先级高的先出其中less是大堆,greater是小堆简单的使用一下:输出:默认是一个大堆 ,大的优先级高但是我想小的优先级高。
2024-05-10 10:18:41
455
原创 stack的使用
我们可以看到模板参数里面有一个容器适配器 ,什么是适配器?比如充电器就叫做电源适配器,用在做转换,对电压进行相关的转换适配我们的设备。栈,队列不是自己直接管理数据,是让其他容器管理数据,在其他容器上去封装转换我想要的东西。和容器 vector,list相比,他们是直接自己管理数据,但是栈不是。
2024-05-08 22:19:48
755
原创 list的模拟实现
const对象只能使用const类型的迭代器,const是只读的,模拟const T*,是指向的内容不可改变,而不是本身不可改变。const_iterator是一个全新的类型,不是const iterator。但是const迭代器和普通迭代器主要区别就是返回值不一样,所以上面的写法太冗余了。使用模板,交给编译器去做。list迭代器不是原生的指针,将节点的指针进行封装,来模拟指针的行为。需要实现重载-> 返回的是A对象的指针,在用->访问其中的成员。如果list存的是自定义类型,怎么访问其中的数据呢?
2024-05-07 22:09:24
1210
原创 vector的oj题
给你一个整数数组nums,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。
2024-05-06 16:44:53
468
原创 vector的模拟实现
迭代器失效:如果失效就不能在使用这个迭代器,如果使用了,结果是未定义的。vs2019进行强制检查,erase以后认为it失效了,不能访问,访问就报错。pos还指向之前旧的空间,扩容后pos失效了,需要更新pos。结论:insert和erase以后迭代器都失效,不能再访问。一般情况下不会失效,但是下面这种情况会失效。是因为扩容中memcpy导致的问题。返回的是删除数据的下一个位置。
2024-05-04 11:13:19
599
原创 vector的使用
其中最最重要的是resize和reserve,max_size是没有意义的接口,告诉能开多大空间,但是实际上不准,所以平时不需要管。易错点:reserve空间开出来就可以访问吗?front和back支持访问头尾的数据,但是一搬习惯于[]先看一下vector的扩容机制。要是想访问,只能用下面的方法。输出:大概是1.5扩容。
2024-05-03 10:00:21
466
1
原创 string的OJ题
给定两个字符串形式的非负整数num1和num2,计算它们的和并同样以字符串形式返回。你不能使用任何內建的用于处理大整数的库(比如BigInteger), 也不能直接将输入的字符串转换为整数形式。思路:从字符串的末尾开始逐位相加,并处理进位。字符转换为数字 -‘0’ 数字转换为字符+'0'// 输出:3。
2024-04-26 20:28:37
253
1
原创 String
范围for,会取s1中的字符赋值给ch,自动判断结束,自动++,原理:编译器替换成迭代器。*it赋值给ch,ch是*it的拷贝,所以不支持修改。但是取别名可以修改,并且范围for不支持倒着遍历。迭代器(遍历数据结构的一种方式),可以想象成一个指针,string就和顺序表一样。2.length,不具有通用性,所以就用size。1.size不算\0,\0是用来标识结束的。3.clear清理数据,不释放空间。const迭代器,只能读,不能写。4.max_size不用管,无用。应用:其中1,2,4用的多。
2024-04-25 15:23:41
252
1
原创 模板初阶(泛型编程、函数模板、类模板)
如何实现一个通用的交换函数呢?使用函数重载虽然可以实现,但是有几个不好的地方:内部的逻辑都是一样的,只是类型不一样。所以就引出模板template。
2024-04-24 10:53:32
997
原创 C++内存分布
以下变量在哪个区?A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)abcd\0在常量区,再把常量区的abcd\0复制给char2,char2 数组在栈上,数组名就是首元素的地址,所以char2在栈上,pChar3是指针,存的是常量区中abcd\0的地址,所以解引用就是指向常量区。ptr1在栈上面,开的空间在堆上面。
2024-04-24 10:06:04
500
原创 C/C++内存管理
int main()//malloc没有办法很好支持动态申请的自定义对象初始化//不会调用构造函数,不初始化//报错,万一有很多个成员,要写很多个get函数//自定义类型,开空间+调用构造函数初始化//自定义类型,调用析构函数+释放空间delete p2;delete p3;A aa1(1);A aa2(2);return 0;应用。
2024-04-23 21:56:02
1439
原创 static、友元与内部类
声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量,用static修饰的成员函数,称之为静态成员函数,静态成员变量一定要在类外进行初始化。面试题:实现一个类,计算程序中创建出了多少个类对象但是这种写法存在缺陷,C++讲究封装,因为C语言随便修改结构中的内容不好,直接越过我访问数据,就会出现很多问题。要是其他人在main函数中--n,--m,结果就完全变了。
2024-04-22 15:27:21
425
原创 初始化列表和explicit关键字
以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个成员变量后面跟一个放在括号中的初始值或表达式。class Datepublic://初始化列表是每个成员定义的地方,_day(day){}private: //每个成员的声明,声明不开空间,对象实例化的时候开空间int _year;//这三个成员什么时候定义,对象实例化的时候整体定义int _month;int _day;混着用_day = day;
2024-04-21 22:10:45
759
1
原创 赋值运算符重载
C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。函数原型:返回值类型 operator操作符(参数列表)比如日期比较大小:不能直接用运算符比较!可以先写一个DateLess函数来比较但是我就是想写d1
2024-04-18 16:56:04
431
1
原创 构造函数和析构函数详解
4.无参的构造函数和全缺省的构造函数都被称为默认构造函数,并且默认构造函数有且只能有一个。注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认构造函数。析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的(对象在栈帧中,栈帧结束就跟着销毁)。总结:一般情况下,我们都需要自己写构造函数,决定初始化方式,成员变量全是自定义类型,可以考虑不写构造函数。3.自定义类型(struct,class,union,..) 会处理,会去调用这个成员的默认构造函数。
2024-04-16 10:02:11
513
原创 类的实例化和this指针
类是存在于文件系统中,在内存中不占空间,类的本质就是设计图纸,图纸不能住人,建成房子才能住人,所以,类中不能存数据,必须实例化为对象才可以存数据。
2024-04-15 17:17:22
1150
1
原创 类与对象(一)
/类体:由成员函数和成员变量组成//一定要注意后面的分号.c文件public://成员函数int Top();private://成员变量int* a;int top;.cpp文件void Stack::Init()//告诉编译器Init是Stack的成员函数//函数中我知道top指向的是哪个位置main函数int main()Stack st;st.Init();st.push(1);st.push(1);
2024-04-15 15:05:43
326
1
原创 指针(二)
这也意味着对数组进行传参时,传递的是数组的引用而不是整个数组的副本,这样可以减少内存的开销和提高程序的执行效率。在C语言中,它允许我们间接地访问或修改指针指向的位置,从而使得我们能够动态地修改指针所指向的内容或指向另一个指针。冒泡排序是一种简单直观的排序算法,它重复地遍历要排序的数组,一次比较两个相邻的元素,并按照指定的顺序交换它们,直到整个数组排序完成。因此,可以通过数组名来操作数组的元素。实际上是数组的地址,所以在函数中传递数组名时,实际上传递的是数组的地址,函数可以通过这个地址来访问数组的元素。
2024-04-02 11:20:17
583
1
原创 指针(一)
假设我们有一个酒店,每个房间都有一个唯一的房间号,并且我们想要查找特定房间号对应的客人。我们可以将每个房间号与客人的姓名关联起来,然后通过房间号来查找对应的客人。在这个例子中,我们可以使用指针来实现这种关联关系。
2024-04-01 17:17:42
427
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人