自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Linux高性能服务器编程学习记录——十五、进程池与线程池

这一章实现了一个半同步/半异步的进程池(主进程只负责监听socket,所有连接socket,以及连接socket上的数据操作由子进程负责),和一个半同步/半反应堆的线程池,主线程负责监听socket和所有连接socket上的IO事件,子线程都阻塞在工作队列中,以竞争的方式从队列中取任务,然后处理。半同步/半异步的进程池实现processpool.h#ifndef PROCESSPOOL_H#define PROCESSPOOL_H#include <sys/types.h>#inc

2022-01-10 14:00:04 493 1

转载 SO_LINGER选项的作用

SO_LINGER选项用于设置函数close()关闭TCP连接时的行为。缺省close()的行为是,如果有数据残留在socket发送缓冲区中则系统将继续发送这些数据给对方,等待被确认,然后返回。利用此选项,可以将此缺省行为设置为以下两种:a.立即关闭该连接,通过发送RST分组(而不是用正常的FIN|ACK|FIN|ACK四个分组)来关闭该连接。至于发送缓冲区中如果有未发送完的数据,则丢弃。主动关闭一方的TCP状态则跳过TIMEWAIT,直接进入CLOSED。网上很多人想利用这一点来解决服务器上出现大

2022-01-06 20:59:07 346

原创 Linux高性能服务器编程学习记录——十四、多线程编程

1、Linux线程概述Linux上两个最有名的线程库是LinuxThreads和NPTL(Native Posix Thread Library),它们都是采用1:1的方式实现的。所谓1:1即一个用户线程对应一个内核线程,内核线程获得cpu使用权就加载和运行用户线程,内核线程相当于用户线程的一个容器。LinuxThreads线程库的内核线程是通过clone系统调用(与fork类似,创建调用进程的子进程)创建的进程模拟的,因此它拥有进程的一些特点。LInuxThreads线程库一个有名的特性是所谓的管理线

2022-01-01 15:54:04 915

原创 聊聊Linux线程的条件变量

条件变量用于同步线程,具体怎么同步的呢,往下看条件变量相关函数#include <pthread.h>int pthread_cond_init(pthread_cond_t* cond, const pthread_condattr_t* condattr); //初始化条件变量int pthread_cond_destroy(pthread_cond_t* cond); //销毁条件变量int pthread_cond_wait(pthread_cond_t* cond, pt

2021-12-31 17:01:51 770

原创 Linux高性能服务器编程学习记录——十三、多进程编程

1、fork系统调用Linux下创建新进程的系统调用是fork#include <sys/types.h>#include <unistd.h>pid fork(void);该调用返回两次,父进程中返回子进程的pid,子进程中返回0,失败返回-1,并设置errno。fork复制当前进程,在内核进程表中创建一个新的进程表项。新的进程表项有很多属性和原进程相同,比如堆指针、栈指针和标志寄存器的值。也有一些属性被赋予新的值,比如新进程的ppid会被设为原进程的pid,信号位图

2021-12-30 14:00:45 615

转载 smb服务的安装

转自:https://blog.csdn.net/whereisherofrom/article/details/80360902

2021-12-27 20:51:29 987

原创 Linux高性能服务器编程学习记录——十一、定时器

这一章其实是对服务器定时器管理的几种实现方案,包括有序链表、时间轮以及小根堆。内容不再详述,下面是摘录自原文的源码。代码清单11-2:升序定时器链表#ifndef LST_TIMER#define LST_TIMER#include <time.h>#define BUFFER_SIZE 64class util_timer;struct client_data{ struct sockaddr_in address; int sockfd; char buf[BUF

2021-12-24 15:24:56 576

原创 Linux高性能服务器编程学习记录——十、信号

1、发送信号Linux下,一个进程给其他进程发送信号的API是kill函数#include <sys/types.h>#include <signal.h>int kill(pid_t pid, int sig);该函数把信号sig发送给由pid指定的目标进程,pid的含义如下Linux定义的信号值都大于0,如果sig取值为0,则kill函数不发送任何信号。2、信号处理方式目标进程收到信号后,需要定义一个接收函数来处理,信号处理函数原型如下#include &l

2021-12-23 14:31:57 1136

原创 Linux高性能服务器编程学习记录——九、I/O复用

在不使用I/O复用的技术下,如果要同时监听多个fd上的事件得使用多个线程(或进程,下同),每个线程单独负责一个fd上事件。而I/O复用技术可以同时监听多个fd,即在一个线程里监听多个fd的事件。另外I/O本身是阻塞的,在它返回后,如果要实现并发,还是得使用多进程或多线程的变成手段。Linux下实现的I/O复用的系统调用主要有select、poll和epoll。1、select系统调用APIselect系统调用的用途是在一段指定时间内,监听用户感兴趣的文件描述符上的可读、可写和异常等事件。#incl

2021-12-21 13:36:53 266

原创 Linux高性能服务器编程学习记录——八、高性能服务器程序框架

1、服务器模型目前主要是C/S(client/server)模型和P2P(peer2peer)模型,不多说。2、服务器编程框架服务器的基本框架如下图:I/O处理单元一般作为接入服务器,负责处理与客户端的连接,读写网络数据,实现负载均衡逻辑单元,顾名思义,就是处理业务的模块网络存储单元一般指数据库请求队列是各模块之间的通信方式,如果是服务器机群的话,一般是TCP永久连接3、I/O模型辛辛苦苦工作了一天,回到家发现女友在打游戏,而没给你做饭,你很生(无)气(语),呵(央)斥(求)她去给你做饭

2021-12-11 10:56:29 380

原创 Linux高性能服务器编程学习记录——六、高级I/O函数

1、创建文件描述符的函数pipe函数#include <unistd.h>int pipe(int fd[2]);成功返回0,并将一堆打开的文件描述符填入fd[],用fd[0]从管道读,用fd[1]往管道写,不能互换。失败返回-1,并设置errno。自Linux2.6.11后,管道容量大小默认65536,可以通过fcntl修改。socketpair函数#include <sys/types.h>#include <sys/socket.h>int so

2021-12-01 20:31:39 222

原创 Linux高性能服务器编程学习记录——五、linux网络编程基础api

1、网络字节序字节序点这里2、socket地址结构体TCP/IP协议族有sockaddr_in和sockaddr_in6两个专用的socket地址结构体,分别用于IPv4和IPv6。struct sockaddr_in{ sa_family_t sin_family; //地址族:AF_INET u_int16_t sin_port; //端口号,要用网络字节序表示 struct in_addr sin_addr; //IPv4地址结构体 见下面};struct in_addr{

2021-11-29 21:25:23 1979

原创 字节序(大小端)问题

现代CPU的累加器一次至少能加载4个字节,即一个整数。这4个字节再内存中的排序将影响它被累加器装载成的整数的值。这就是字节序问题。字节序分为大端序与小端序,即big endian、little endian。大端序是指一个整数的高位字节存储在内存地址的低地址处,低位字节存储在内存高地址处。小端序正好相反。下面看0x0102在两种内存结构中的存储方式。0x0102占两个字节:高位字节 01:0000 0001,低位字节02:0000 0010内存地址位: 低 ----------------&g

2021-11-23 14:11:43 2245

原创 TCP/IP详解:TCP——保活机制

1、保活时间、保活时间间隔、保活探测数如果在一段时间(保活时间:keepalive time)内连接处于非活动状态,开启保活功能的一端奖项对方发送一个保活探测报文。如果发送端没有收到响应报文,那么经过一个已经提前设置好的保活时间间隔(keepalive interval),将继续发送保活探测报文,直到发送探测报文的次数达到保活探测数(keepalive probe),这时对方主机将被确认为不可到达,连接将被中断。保活探测报文为一个空报文段(或只包含一个字节)。他的序列号等于对方主机发送的ACK报文的最大序

2021-11-18 14:00:40 2495

原创 TCP/IP详解:TCP——拥塞控制

TCP/IP详解:TCP——拥塞控制1、拥塞检测没有一个精确的方法或者说一个明确的信号告知发送方拥塞状况是否已发生。通常看是否有丢包情况来推断是否出现拥塞。在TCP中,丢包也被用作判断拥塞发生与否的指标,用来衡量是否实施相应的响应措施。 注意:在当今的有线网络中造成丢包的主要原因是拥塞,而在无限网络中却是传输和接收错误。二、使用步骤1.引入库代码如下(示例):import numpy as npimport pandas as pdimport matplotlib.pyplot as

2021-11-18 09:23:53 2656

原创 TCP/IP详解:TCP——数据流与窗口管理

1、PSH位PSH标志位通常表示发送端缓存为空,也就是说,当PSH置位的数据包发送完成后,发送端没有其他数据包需要传输。2、延时确认很多情况下TCP并不是对每个到来的数据包都返回ACK,而是在累计几个包后返回一个ACK,实践中最大时延一般取200ms,对于批量数据传输一般是2:1的比例,ACK计时器超时时间以及超市前在传的ACK数目都可以配置。3、Nagle算法Nagle算法要求,当一个TCP连接中有在传数据(即那些已发送但还未经确认的数据),小的报文段(长度小于SMSS)就不能被发送,知道所

2021-11-06 13:24:06 1037

原创 TCP选项(持续更新)

很多初学者在学习TCP协议是比较关注的是TCP头部中的各字段,往往会忽略TCP选项。本文将梳理下TCP选项中个字段的含义。1、最大段大小MSS(Maxitum Segment Size)种类号2,长度4(Bytes)最大段大小是指TCP协议所允许的从对方接收到的最大报文段,因此这也是通信双方在数据交换过程中能够使用的最大报文段。这个值是在建立tcp连接的三次握手中双端协商得到的。p1发送SYN包来请求建立连接,在这个包中,mss选项字段会填充自己一端能接收的mss值,典型值为1460,p2在回应的

2021-11-06 11:24:12 389

原创 TCP/IP详解:TCP——超时和重传

1、TCP一般拥有两套独立机制来完成重传,一是基于时间,即超时重传,而是基于确认信息的构成,即快速重传。2、RTT(Round Trip Time) 往返时延,数据包从发出到收到对应ACK的时间,每一条连接都有独立的RTT。RTO(Retransmission Time Out)重传超时,即超时时间。RTT和RTO都是动态变化的。3、超时重传的时间间隔是不一样的,一般采用的是二进制指数退避策略,比如第一次间隔3s,第二次6s,然后12s、24s ...4、计算RTO的经典方法最初的TCP规.

2021-10-31 15:26:01 2046

原创 TCP/IP详解:TCP——连接管理

1、每一个TCP连接由一个四元组构成,更准确的说是一对端点或套接字。2、连接建立的过程称为三次握手,三次握手的目的不仅在于让通信双方了解一个连接正在建立,还在于利用数据报的选项来承载特殊的信息,交换初始序列号tcp连接建立和关闭的过程3、TCP半关闭由于一条tcp连接支持双向通信,因此存在一种情况:我还可以接收你发的数据,但我不再给你发送数据(数据确认包还是会发送的)。这种情况称为半关闭,套接字的shutdown()函数实现这种操作。4、同时打开与关闭同时打开与关闭是发生在同..

2021-10-26 13:49:53 796

原创 TCP/IP详解:TCP——初步

1、ARQ(Automatic RepeatRequest自动重复请求)和重传一个直接处理分组丢失或比特差错的方法是重发分组,那么发送方如何判定需要重发呢?引入接收方的确认机制ACK(Acknowledgment)。接收方在接收到一个正确的分组后给发送方发送一个ACK。于是又引入了三个问题:发送方对一个ACK应该等待多长时间 如果ACK丢失了怎么办 如果分组被接受了,里面有错怎么办问题1比较复杂,之后讨论。对于问题2,发送方不能轻易地把这种情况和分组丢失了区分开来,他只能再次发送原分组。问题.

2021-10-06 13:57:44 145

原创 TCP/IP详解:用户数据报协议(UDP)和IP分片

1、UDP8字节头部其中校验和字段是对包含了IP头部中的源和目的IP地址字段的udp伪头部计算得到的。包含IP地址的伪头部只在计算校验和的时候用到,实际传送的udp头部只有8个字节。另外,udp头部中的长度字段是冗余的,udp的长度完全可以通过ip数据报总长减去ip数据报头部长度得到。2、udp校验和计算时覆盖的字段要注意的是在IPv4的udp中,校验和是可选的(但是强烈建议),而在IPv6中是强制的,因为IPv6的IP层没有头部校验和。当一个udp的校验差错被检测到时,这个数据报.

2021-10-05 15:53:08 1220

原创 TCP\IP详解——第4章:ARP:地址解析协议

1、ARP提供IP地址到对应硬件地址的动态映射,RARP正好相反2、ARP请求过程数据在网络中传输时都是要把目的IP地址转为硬件地址的,这件事由ARP来完成。ARP会在网络上广播一个称为ARP请求的以太网数据帧,来询问“这个目的IP地址是谁的,请把你的硬件地址告诉我”。目的主机(或路由器)在收到ARP请求后,回复一个ARP应答告知自己的硬件地址,这样ARP就完成了目的IP到目的硬件地址的转换3、ARP高速缓存高速缓存存放了最近的IP地址到硬件地址的映射记录,这项记录的有效时间一般被设为20分

2021-09-05 16:49:08 147

原创 TCP\IP详解——第3章:IP:网际协议

1、IP仅提供最好的传输服务,不保证数据报能否成功到达目的地。任何要求的可靠性必须由上层来做(如TCP)2、IP首部普通的IP首部占20字节,除非含有选项字段。下图是IP数据报的格式(图片来自TCP\IP详解卷1)3、IP首部校验和先把检验和字段置为0,然后对首部中每个16位进行二进制反码求和(整个首部堪称是一串16bit的字组成),结果存到检验和字段中。收到这份ip数据报后同样再对每个16bit反码求和,结果应该为全1(二进制),否则丢弃数据报。看下面例子45 00 00...

2021-09-05 14:45:14 135

原创 TCP\IP详解——第2章:链路层

1、环回接口大多数系统把IP地址127.0.0.1分配给这个接口,并命名为localhost,一个传给环回接口的数据报不能在任何网络上出现传给环回地址(一般是127.0.0.1)的任何数据均作为IP输入。 传给广播地址或多播地址的数据报复制一份传给环回接口,然后送到以太网上。这是 因为广播传送和多播传送的定义(第 12章)包含主机本身。 任何传给该主机I P地址的数据均送到环回接口 ...

2021-09-02 19:31:03 64

原创 TCP\IP详解——第1章:概述

1、TCP\IP四层协议系统应用层(Telnet、FTP、HTTP等) 传输层(TCP、UDP) 网络层(IP、ICMP、IGMP) 链路层(物理层)2、五类互联网地址格式

2021-09-02 13:39:12 53

原创 c++Primer——第十九章:特殊工具与技术

1、哪些情况需要定制new和delete(effect c++ item50)用来检测运用上的额错误 为了强化效能 为了收集使用上的统计数据

2021-09-01 20:49:21 112

原创 c++Primer——第十八章:用于大型程序的工具

1、当抛出一个异常后,程序会暂定当前函数的执行过程并以栈展开的方式寻找与异常匹配的catch字句,若找不到catch,程序将调用标准库函数terminate,终止程序的执行。2、栈展开过程中编译器会确保退出块中已创建的对象能被正确地销毁,如果对象是类类型的话,它的析构将被调用。3、析构中不应该抛出异常在栈展开过程中运行类类型局部对象的析构函数(可以看出析构函数成了异常处理的一部分),因为这些析构函数是自动执行的,所以它们不应该抛出异常(这时的析构本来就是用来处理异常的,它再抛出异常的话,那由谁来

2021-08-25 10:08:32 100

原创 c++Primer——第十七章:标准库特殊设施

1、std::tuplestd::tuple<int, string, vector<int>>t{ 5, "abc", {1,3,5,7} };//获取t的类型typedef decltype(t) ttype;//获取t中成员数量size_t sz = tuple_size<ttype>::value;//打印成员cout << get<0>(t) << endl;cout << get<1&g

2021-08-21 14:44:16 81

原创 c++Primer——第十六章:模板与泛型编程

1、在模板的类型参数前必须使用关键字class或typename,在模板参数列表中这两个关键字的含义相同,可以互换使用。2、默认情况下,对于一个实例化了的类模板,其成员只有在使用时才会被实例化3、在一个类模板的作用域内,我么可以直接使用模板名而不必指定模板实参4、在普通代码中,由于编译器掌握类的定义,因此它知道通过作用域运算符访问的名字是类型还是static成员,但对于模板代码就存在困难。如:T::mem,编译器并不知道mem是类型还是static成员。c++默认通过作用域运算符访问的不是类型,

2021-08-20 13:16:01 123

转载 计算机字符编码的前世今生

转自:https://mp.weixin.qq.com/s/wqUm4AEc5V0Rl9Au1DSK4A一、前言有人丢给你下面这张图,如果你能清楚地说明它们之间的关系以及用途,那么你对字符编码的理解肯定过关了。不知道看了上面这张图,是否有混乱的感觉,本文试着给你梳理、讲透这些孤立的几个单词之间联系......二、关于字符编码,你所需要知道的2.1 ASCII(寡头垄断时期)计算机内部,所有信息最终都是一个二进制值。每一个二进制位(bit)有0和1两种状态,8个

2021-08-17 11:15:19 99

原创 c++Primer——第十五章:面向对象程序设计

1、动态绑定c++中当使用基类的引用或指针调用一个虚函数时将发生动态绑定。2、虚函数继承如果基类吧一个函数声明成虚函数,则该函数再派生类中隐式地也是虚函数。3、派生类构造函数尽管再派生类对象中含有从基类 继承而来的成员,但是派生类并不能直接初始化这些成员。和其他创建了基类对象的代码一样,派生类也必须使用基类的构造函数来初始化它的基类部分。每个类控制它自己的额成员初始化过程。class A{public: A() :a(0) { cout << "A cons"

2021-08-11 21:06:26 262

原创 c++Primer——第十四章:重载运算与类型转换

1、对于一个运算符函数来说,它或者是类的成员或者至少含有一个类类型的参数。2、不能被重载的运算符::.*.?:而通常情况下,不应该被重载的运算符, & && ||3、当我们把运算符定义成成员函数时。它的左侧运算对象必须是运算符所属类的一个对象// 假定 + 是string的成员string s = "world";string t = s + "!"; //正确 ...

2021-08-07 13:56:38 85

原创 c++Primer——第十三章:拷贝控制

1、拷贝控制操作拷贝构造函数 拷贝赋值运算符 移动构造函数 移动赋值运算符 析构函数2、只要我们显示的定义了一个构造函数,编译器就不会替我们再定义任何形式的构造函数class A{public: A(int a):x(a){} void set(int a) { x = a; } int get() const { return x; }private: int x;};void test(){ A a; //错误 没有默认构造函数 A a2(3); //正确

2021-08-06 13:11:54 325

原创 c++Primer——第十二章:动态内存

1、三种内存分配方式静态内存:局部static对象、类static成员、全局变量 栈:局部非static对象 堆:程序运行时动态分配的对象2、智能指针概述shared_ptr:允许多个指针指向同一个对象 unique_ptr:独占所指向的对象 weak_ptr:一种指向shared_ptr管理对象的弱引用,为解决shared_ptr的循环引用问题而提出的3、内存耗尽一旦一个程序用光了所有可用的内存,new就会失败,默认情况下,会抛出一个类型为bad_alloc的异常。但是我们可以改变

2021-08-03 13:18:11 150

原创 c++Primer——第十一章:关联容器

1、关键字类型要求对于有序容器——map、multimap、set、multiset,关键字类型必须定义元素比较的方法。默认情况下,标准库使用<运算符比较关键字。习题11.10:可以定义vector<int>::iterator到int的map,但是不能定义list<int>::iterator到int的map。因为list的迭代器不支持比较运算。2、关联容器的迭代器map的迭代器的first成员保存的是const 的关键字,set的迭代器是const的,虽然他

2021-07-30 13:15:18 138

原创 c++Primer——第十章:泛型算法

1、find、count、accumulate、equalaccumulate的第三个参数的类型决定了函数中使用哪个加法运算符以及返回值的类型 vector<string> svec1; vector<double> dvec2; string sum = accumulate(svec1.cbegin(), svec1.cend(), string("")); // 正确 string sum = accumulate(svec1.cbegin(), svec1.c

2021-07-28 19:00:50 121

原创 c++Primer——第九章:顺序容器

1、几个迭代器begin、end、cbegin、cend、rbegin、rend、crbegin、crend2、与顺序容器大小相关的构造函数顺序容器(array除外)提供一个构造函数。它接受一个容器大小和一个(可选的)元素初始值,如果我们不提供元素的初始值,则标准库会创建一个值初始化器。如果元素类型是没有默认构造函数的类类型,则除了大小参数外,还必须指定一个显式的元素初始值。3、标准库array使用array必须同时指定元素类型和大小 array<int, 3> arr

2021-07-26 20:50:56 192 3

原创 c++Primer——第八章:IO库

1、IO对象无拷贝或赋值,所以不能将形参或返回类型设置为流类型 ofstream out1, out2; out1 = out2; //错误 不能对流对象赋值 ofstream print(ofstream); //错误 不能初始化ofstream参数 out2 = print(out1); //错误 不能拷贝流对象2、流的状态一个流一旦发生错误,其上后续的IO操作都会失败,由于流可能处于错误状态,因此代码通常应该在应用之前检查它。确定一个流对象的状态的最简单的方法是将他当作条

2021-07-24 14:35:17 156

原创 c++Primer——第七章:类(基础,后面还会讲到)

1、构造函数只有当类没有声明任何构造函数时,编译器才会自动地生成默认构造函数。但有时候编译器不能为类合成默认构造函数,例如类中包含一个其他类类型的成员且这个成员没有默认构造函数,那么编译器将无法初始化该成员。当然还有一些其他情况,将在13章中介绍。c++11中可以通过在参数列表后写上 =default;来让编译器生成构造函数。2、struct和class的唯一区别是默认的访问权限,前者默认public,后者默认private。3、可变数据成员通过在变量的声明中加入mutable关键字可以

2021-07-23 21:05:47 88

原创 c++Primer——第五章:语句

1、函数在遇到异常后寻找处理代码的过程中退出当异常被抛出时若没有找到匹配的catch语句或者本没有try语句块的定义,程序会转到名为terminate的标准库函数,该函数与系统有关,一般情况下,执行该函数将导致程序非正常退出。...

2021-07-22 13:58:48 70

空空如也

空空如也

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

TA关注的人

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