- 博客(37)
- 收藏
- 关注
原创 Linux系统编程8 信号
内核会暂停该进程正在执行的代码,并跳转到先前注册的函数中,接下来会执行这个函数。但其会继承信号处理函数和信号注册函数signal()和handle().若子进程未设置alarm()函数,则父进程只会执行一次。首先产生信号,接着内核储存信号,直到可以发送信号,最后一旦空闲,就处理信号。进程可以捕捉该函数,并在进程结束前进行清理,但是捕获该信号并不能及时地终止进程。SIGTERM:该信号由kill()函数发出,其循序用户优雅地停止进程,调用fork()函数时,子进程会继承父进程的所有信号的。
2024-08-08 16:44:17
661
原创 Linux系统编程7之文件和目录管理。
LINUX系统中,目录就是包含一个文件列表名,每个文件名映射一个INODE编号,每个文件称之为目录项,目录当然还可能包含其他目录,子目录。路径名由文件名及其一级或者多级父目录组成的,绝对目录是从根目录开始的,相对目录从当前所在目录开始。):以下宏是对于调用open/creat函数创造新文件时进行赋予的文件权限,而不是O_()的宏,后者是以什么方式进行操作文件,这是两个不同,要区别。即是UNIX类的文件系统的物理对象,也是LINUX内核数据结构描述的概念实体,inode储存了与文件相关的元数据。
2024-08-05 13:28:26
827
原创 LINUX系统编程5之线程(简单介绍相关函数和知识)
具体用法见网络编程部分,对于LINUX来说,其锁的涉及稍微简单,可以参考C++标准库中的锁的分类,shared_mutex,unqie_lock,share_lock,mutex等等。对于新线程,默认状态是允许,如果线程不允许取消,请求会入队列,直到允许取消。1.基本知识:进程是操作系统对运行的二进制程序的抽象,包括:加载的二进制程序,虚拟内存,内核资源等等。这里注意,新的线程会共享父进程资源,而不是进行拷贝。上述两个应该在进程中的每一个线程上进行调用,这样当线程终止时,也会释放系统资源。
2024-07-31 12:10:55
319
原创 Linux系统编程4:进程应用
内核分配进程ID是以线程来递增的,比如主进程的PID为17,这时再创建按一个进程,其PID一定是18,以此类推。每一个进程都有唯一的标识符进行表示:操作系统保证在每时刻PID都是唯一的。每个进程都是某个进程组的一部分。进程组表示的是该进程和其他进程之间的关系,子进程通常属于父进程所在的那个进程组。创建新进程的那个进程被称为父进程,而新进程被称之为子进程。每个子进程都有一个父进程。在LINUX系统中:每个进程都属于某个用户的某个组的,每个子进程都继承了父进程的用户和组。1).获得父进程和进程ID。
2024-07-28 10:28:55
943
原创 网络编程之如何使用多进程结合EPOLL实现一个简单的并发聊天室
上述只要注意semop()函数的第二个参数是struct sembuf类的数组。则semop()调用时,对其中每一个元素都进行原子操作。semget()函数第一个参数类似于文件的文件描述符,每一个信号集对应有且只有一个映射。第三个参数表示了信号集的权限和一些信息。只需要注意:调用方式和open()一样。本章主要补充LINUX下的一些多进程编程的系统调用和进程池的用法。其都定义在或者semop()函数进行PV操作,改变信号量的值。上述信号量的初始情况要明白。
2024-07-24 15:35:12
228
原创 Linux 系统编程2:缓冲I/O(标准I/O)
这里提一点:标准I/O其实性能比较低,当读数据时,标准I/O会向内核发起read()系统调用,将数据拷贝在标准I/O缓存中,然后通过标准I/O的fget请求,又会拷贝一次到指定缓冲区。该函数从stream中读取size-1个字节,保存在str中,读取最后一个字节后,缓冲区会写入'\0',读到EOF或换行符时,读结束,换行符'\n'写入str中。2).可以通过函数fdopen()把一个已经打开的文件描述符(open()或网络编程函数创建的可以进行读写的文件描述符)2).每次读取一行的数据,函数fgets()
2024-07-23 12:09:45
401
原创 网络编程之LINUX信号
sa_mask是成员设置进程的信号掩码,用于内核进行运算执行,其是信号集sigset_t类型。信号集就是一个数组,类似于fd_set,该数组的每一位都表示一个信号。对于网络编程,一般不需要设置特殊的sa_mask.用函数。总结就是设置信号处理函数时,处理函数将收到信号通过管道方式传递给主循环进行聆听判断,对不同信号做出相应的反应。注意发送信号是给进程,不是线程,调用的是KILL函数,SIG是信号种类。对于是暂停信号的接受,没有设置信号的处理函数,则会中断epoll_wait,connect等调用。
2024-07-21 16:29:30
461
原创 Linux系统编程1-----文件I/O(对于文件)
2号参数是监听是否有数据可读,3号参数是监听是否有某个写操作是无阻塞完成的(即在监听事件内是否有通过文件描述符发生写事件),4号参数是监听监听的文件描述符是否有异常或者是出现外带数据等。对于网络编程来说,此两个函数不能用socket专属文件描述符去配合设置并使用,始终成为非阻塞I/O,但是可在系统编写文件的文件描述符下(open()调用),使之成为阻塞,非阻塞I/O。注意,创建文件时,用户对每一个文件都有属性,假如用户对该文件只有读权限,就不能以写的方式打开它,反之依然,可以通过命令修改文件用户权限.
2024-07-20 21:25:54
724
原创 网络编程11笔记
二部分是请求头部:请求头部包含多个字段,比如connection字段、Cache-Control字段等,中间有个冒号,冒号后面是该字段具体的值。HTTP服务器的主要功能是:在浏览器端访问服务器IP+html文件名,结果为如果服务器存在我们想要的HTML文件,则会将其展示在浏览器端。上述代码简化了 只有请求行和消息头,且只分割请求行,不包括消息行,只需注意一点就是用字符串函数如何进行分割字符串即可。HTTP服务器是基于TCP/IP协议的,上图只是简单的消息发送过程,下面是简单的http服务器代码。
2024-06-04 21:40:08
61
原创 网络编程9
对于描述select函数(I/O复用),其无法拓展到同时连接上百个客户端,因为首先针对的是所有文件描述符的循环操作(不是将所有发生变化的文件描述符集中在一起,而是通过轮询的方式查找),第二个是每次调用SELECT函数都需要向其传递监视对象消息(向操作系统传递监视对象消息,这样的开销是巨大的。相比大家都学过操作系统,这里就不多做介绍了。对应文件指针,"w"对应只能是fpus "r"(写,写给谁,写的消息从哪里来) ,读操作,对应的函数操作是fgets(三次参数,读取后存在哪个地方,从哪里读取)
2024-05-28 17:36:21
1477
原创 网络编程入门笔记8
调用MSG_PEEK后,客户端传输给服务端,服务端从输入缓冲中接受并储存在一般缓冲区后,输入缓冲的数据不会被删除,下次若调用recv函数 第四位参数设为0,还可以接受上次的数据,然后从输入缓冲中删除。注意多播只传输一次数据,但是会传给分组的所有客户端,多播虽然是基于UDP传输的,但是传输多播数据包时,经过路由时,路由会复制数据包传输给所有分组用户。多播的数据传输方式是依靠UDP传输的,回忆以前的UDP服务客户端,都是单一传播的,但是多播数据是同时传递到加入(注册)特定组的大量主机。
2024-05-25 18:56:06
1515
原创 网络编程7笔记:
如上,首先需要一个数组(本质是用结构体封装的数组)集合文件描述符,对于数组里面的文件描述符也需要做区分,例如上图的0和1,0说明该位的文件描述符不是监听对象(未注册文件描述符),如果是1,则该位文件描述符是监听对象(注册了文件描述符)(特定数组:fd_set类型的数组,即申明fd_set变量时,该变量是结构体,将其看作数组)如上图:调用函数前,先设置监听对象,从0变为1,调用函数后,数组重置为0,若有监听的文件描述符从零变为1,说明该位的文件描述符发生了监听事件,如上图fd1 fd3发生了监听事件。
2024-05-23 11:31:23
1331
原创 网络编程入门编程5
左边是使用了NAGLE算法,TCP套接字默认使用NAGLE算法,如图:当其收到上一次传输的ACK后才会才会传递接下来的数据。一共只要四个数据包。但是计算机的默认DNS服务器不是知道网络中所有的域名对应的IP地址,所以其会访问其他的DNS服务器,以至于获得IP地址。先断开的会经历Time_wait,如果先断开的是服务器段,在这段时间内服务端重启时,bind()函数会调用失败,见下图。下面介绍的是该结构体的结构。h_lengh保存的是网络地址的长度,如果是IPV4,则保存的是4,如果是IPV6 则是16.
2024-05-18 11:02:06
184
原创 网络编程4
UDP性能比TCP高。对于TCP服务器,双方调用IO函数的次数不是很重要,但是对于UDP服务器,双方调用的IO函数操作次数必须要相同 比如客户端发送三次信息,服务端就必须要接受三次信息。在创建TCP套接字时已经赋予了IP地址和端口,传输数据时,无需指定地址,因为TCP套接字知道对方目的地,但是UDP不知道,因此每次传输数据时会要传送目标地址信息。上述中我们发现UDP在调用时,为对套接字分配目标主机的地址和端口号,在TCP服务端中是通过调用connect函数自动赋予的,UDP是调用SENDTO函数时赋予的。
2024-05-15 21:09:16
187
原创 网络编程3
但不论客户端如何传递信息,客户端都能接受信息并且返回。因为只要客户端传来信息,服务端就能调用READ函数 就能调用WRITE函数。TCP没有数据边界,每一次调用WRITE函数就会传递一个字符串,多次调用WRITE函数可能一次传给服务端。并且注意WRITE函数的返回时间不是完成向对方数据传输时返回,而是将数据移除缓冲区时返回。解决方法就是提前确定接受数据的大小,比如之前发送了20个字符,接受数据到20个字符即可。调用write:数据被移出缓冲区,适当时刻传入对方的缓冲区当中。
2024-05-13 13:26:25
173
1
原创 effective c++ 12
即不要让operator=函数调用copy构造函数(试图构造一个已经存在的对象,这是荒诞的),不要让copy构造函数调用operator=函数(都没初始化和创建,你怎末赋值。1.对于拷贝复制构造,构造函数 ,拷贝构造操作符,当你为类中添加了新的元素时,要重新改变上面三个函数,确保每一个变量都能被赋值(还是记住 重载=的函数返回this指针)2).当继承时,子类不仅有自己的成员 还有基类的成员 那么在调用子类的构造函数(多种)初始化类成员时,不要忘了通过子类的构造函数调用基类的构造函数从而去。
2024-05-10 13:20:50
183
原创 linux环境下的文件操作
linux系统下一切都是文件 open函数作为打开方式,打开成功返回打开文件的文件描述符。要关闭文件 用到close函数。读取成功后存入在数组中。
2024-05-08 21:22:07
135
原创 网络编程 C++2
IP层仅仅只会关注一个数据包 IP层的数据传输是不可靠的,如果指利用IP层进行数据传输,那么可能会导致后传输的数据包比先传输的数据包先接受或者传输 A B C三个数据包只能受到A B两个,更甚至是C已经损失。从上图可知,在调用ACCEPT函数后,紧接是调用I/O函数进行读写,之后关闭的是ACCEPT函数接受客户端创建的套接字,而不是服务器套接字。总结:对于以上的服务器连接只是单个连接,这样不是实际开发利用的,下面将介绍迭代服务器,依次进行连接,讲等待列队的所有连接请求相连。如下是connect函数。
2024-05-06 17:29:26
260
3
原创 effective c++条款10,11
这里的问题就是:operator内的*this和fhs可能指向同一个对象 那么delete销毁的是fhs和当前对象的pd指向指向的相同的变量,之后将自己持有的指针指向一个已经被删除的对象,这样很明显是错误的。2.对于一般的代码段操作指针或者引用而他们被用来指向或引用多个相同的对象 就需要考虑这些对象是否属于同一个,往往会有一些隐藏危险 比如。总上 .确保自我复制时 operator=有良好的操作 且任何函数操作一个以上的对象,1.对于重载运算符,最好返回this* ,这样的类型可以实现赋值连锁形式。
2024-05-05 21:13:45
111
2
原创 字符串算法之KMP
KMP算法定义了next数组 next[i]表示 以角标i的字串的前后缀的公共字串长度。比如字符串abcde,此字符串的前缀是a.ab,abc,abcd。字符串abcde: e de cde bcde。对于其中next数组的作用是用于next指针回退。前缀:一个字符串除了最后一个字母的所有组合。后缀:一个字符串除了最前面一个字母的所有组合。如下代码是next数组的数组的实现。1.首先要明白前缀和后缀的概念。
2024-05-03 20:24:07
213
原创 effective C++ 条款9,10
首先在B类变量中 继承部分中A的构造函数肯定先被调用,那么就会调用A中的虚函数(先把log当作虚函数,不看=0),但是成员变量和环境都是属于B的,说明base class构造期间虚函数不会下降到derived class阶层。本质是编译器在此阶段都解析为基类信息,如果此虚函数可以下降到子类阶层,则会调用子类的重写函数,但此时子类并未初始化,编译器不会允许这样危险的操作,并且log是纯虚函数,不能在基内定义,只能申名,所以无法被链接,找不到函数的方法。),直接调用纯虚函数是编译器不允许的。
2024-05-01 11:46:59
42
原创 effective c++ 条款7
所以比如子类中开辟了动态内存 但接受是父类引用或者指针,在程序结束时不会调用子类的析构函数,而是调用父类的析构函数,这变会导致内存泄露。所以如果不具备多态性的基类,没必要设置虚函数 ,析构函数虽然函数名不同,但是也可以构成重写.因为编译器为了让析构函数实现多态,会将它们的名字都处理为destructor,这样就可以构成多态.1.首先回忆 C++中的多态分为静态多态和动态多态,前者是在编译期中发生,主要是宏多态和函数多态,后者发生在运行期间 主要是继承和虚函数。条款7规定为多态基类申明虚析构函数。
2024-04-29 16:12:08
86
原创 网络编程笔记入门 1
计算机内部由NIC(数据传输设备),NIC向计算机内部传数据时用到IP,操作系统会负责把数据传给合适的套接字,这就要利用端口号(通过NIC的数据由端口号,参考端口号分配给合适的套接字)3.对于两个人打电话,套接字就相当是座机,当有了座机以后,为了通话,就要给座机分配电话号和座机号,同样对于套接字,要完成通话就要给其分配IP地址和端口号,使用如下函数bind。调用inet_addr函数。用此函数可以创建一个套接字,此函数的第一个代表协议族,第二个参数代表套接字的数据传输方式,第三个参数代表选用的最终的协议。
2024-04-29 13:52:42
152
原创 effective c++ 6
第二张图的错误直接发生在连接期,解决第二张图的错误就是使用friend或者member函数。对于第一张图,将连接期的错误移动到编译期 程序不会直接显示错误。这样,对于第一张图 任何人即使使用friend或者member函数 尝试拷贝 A对象,编译器都会尝试生成一个拷贝构造函数和拷贝操作符.4.对于编写赋值运算符是 要记住 大多数赋值运算符组合了拷贝构造函数和析构函数 且将一个对象赋予时,赋值运算符要能够正确工作,最好是。1.对于不想调用编译器自动生成的函数,你可以自己重新声名函数。
2024-04-28 19:15:53
152
原创 effective c++5
2.对于string类的引用 是不能用c风格字符串来初始化和赋值的 因为const char*不能转化为string&类 所以可以对const string&用c风格字符串来初始化和赋值的。只有这些函数需要被调用时才会被创建出来,还要注意的就是 编译器创造的默认析构函数不是虚函数,而对于重载运算符=则是只能对非static对象使用。一定要养成定义重载和调用显示构造函数的习惯 拒绝调用编译器默认生成的函数并且尽可能用string类 不要用c风格字符串。
2024-04-27 15:31:42
150
原创 C++中的stringstream操作
3.string类的操作比较多 容易忘,记住string是重载了+,但其他相关容器没有c风格字符串则是以函数操作,想strcmp,strcat,strcpy等等,读者要熟练运用string类,再提一下vector或者array 的string类,其就是类似于二维数组,这小点需要注意下。要注意的是对于第一种的流入方式类似于对字符串的追加,而第二种方式则是直接进行覆盖操作。1.stringstream中的构造函数: 有两种。4stringsteam指定字符分割字符串。这需要利用到getline函数。
2024-04-26 13:54:41
196
原创 effective C++ 4
1.确定变量在使用前已经被初始化 尤其是对应指针变量 在初始化和被销毁时(除开智能指针),一定要进行制空,防止变为野指针 对于除去内置函数的其他类,初始化落实在构造函数上,在构造函数中,尽量不要用赋值初始化 ,直接初始化的效率更高。3.对于类中成员初始化时 其初始化顺序一定要和在class中的申明顺序是一样的 这个要注意。4.对于跨文件编程 将static对象转换为非static对象。2.对于成员变量是const或者是reference 则。一定需要初始 而不是赋值。
2024-04-26 11:31:51
121
原创 C++字典树的实现
力扣211 是上类字典树的变种,即单词中如果有".",其可以代表任何的字母 所以在匹配的时候遇见是要遍历当前层的所有结点 只要找到一个就可以满足。本文章参考力扣208与211,建议未学过的小伙伴去看看,本文章只附上字典树的建立,查找等。
2024-04-25 14:04:23
119
原创 effective C++ 3
非const成员函数可以访问非const对象的非const数据成员、const数据成员,5.对于类的重载函数 其参数必须要有一个引用类型 ,如果要通过函数改变一个类变量的内部值,传的也是引用 ,所以 对于类成员函数的形参 要养成用引用的习惯。作为一种良好的编程风格,在声明一个成员函数时,若该成员函数并不对数据成员进行修改操作,应尽可能将该成员函数声明为const 成员函数,所以,如果类中有非const和const修饰的函数,函数内容相同,const修饰的函数会先调用const修饰的变量。
2024-04-23 16:48:31
136
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人