现代C++
现代C++lambda1int main() { static int a = 42; auto p = [=] { ++a; } ; std::cout << sizeof p << '\n'; p(); return a;}// 1 43
如果变量满足下列条件,那么 lambda 表达式在使用它前不需要先捕获:该变量是非局部变量,或具有静态或线程局部存储期(此时无法捕获该变量),或者该变量是以常量表达式初始化的引用。
这里的捕获是[=],但是其实写不写都无所谓,反正这个作用域就一个静态局部变量a,你也无法捕获到这个变量。那么按照空类,p的大小一般来说自然也就是1了。
2int main() { const int N = 10; auto p= [=]{ int arr[N]{}; }; std::cout<< sizeof p;}// 1
1.如果变量 ...
TCP协议栈
TCP协议栈listen
构建tcp control block(tcb)
将状态置为listen
connectint connect(fd, serveraddr, sizeof);
找到fd对应的tcb
发送syn包
acceptint accept(fd, clientaddr, &len);1. while(acceptqueue == NULL) {pthread_cond_wait();}2. *tcb = get_tcb_from(acceptqueue);3. clientfd = get_fd_fdtable();4. 根据tcb去找对应的clientfd
确定网络包在半连接队列的节点
通过五元组(sip, dip, sport, dport, proto)
tcb通过五元组确定其唯一性
bind
socket创建一个fd
bind将fd与tcb (ip, port)进行绑定,但是不改变tcb状态
close
大量close_wait
没有及时调用close:将清理缓冲区剩余数据交给线程池,进行异步操作
大量fin ...
Coroutine Scenarios
Coroutine ScenariosGenerator
可以挂起返回很多值
当挂起的caller恢复运行时,使用value
Lazy sequence
实现iterator/sentinel
// C++23实现该标准库std::generator<uint64_t>fibonacci_sequence(unsigned n) { if (n > 0) co_yield 0; if (n > 1) co_yield 1; uint64_t a = 0, b = 1; for (unsigned i = 2; i < n; ++i) { uint64_t s = a+b; co_yield s; a = b; b = s; }}
Task
类似函数调用的感觉
Caller co_await当task被创建
task<T>::await_suspend()存放caller-handle(in its promise)同时开 ...
网络编程
网络编程最简单socket编程int sockfd = socket(AF_INET, (struct sockaddr*)&serve_addr, sizeof(struct sockaddr));listen(sockfd, 10);struct sockaddr_in client;socklen_t len = sizeof(client);int connfd = accept(sockfd, (struct sockaddr*)&client, &len);while (1) { unsigned char buffer[BUFFERSZ] = {0}; int ret = recv(connfd, buffer, BUFFERSZ, 0); if (ret == 0) { shutdown(connfd, SHUT_WR); } ret = send(connfd, buffer, ret, 0);}
问题
客户端发送时,另外一个客户端 ...
智能指针
智能指针
智能指针分配在栈中,但是指向的对象在堆中
智能指针的ref count是线程安全的,但是修改数据,数据是线程不安全的
shared_ptr
内部存在两个指针
一个指向分配的对象
一个指向控制块
reference count(引用计数)
weak count(弱计数)
other data(custom deleter, allocator)
shared_ptr<Buffer> buf1 = std::make_shared<Buffer>("Hello world");shared_ptr<Buffer> buf2 = buf1; // 两个shared_ptr指向的内容相同,只是引用计数增加
unique_ptr
独占指针,没有copy语义
weak_ptr解决的问题
可以解决shared_ptr循环引用的问题(A指向B,B指向A)
多线程环境下, 先锁定资源(lock), 再判断资源是否可用(expire);
Red-Black Tree
B Tree定义
每个结点至多拥有M棵子树(最大结点关键字个数)
根结点至少拥有两棵子树
除了根结点以外,其余每个分支结点至少拥有M/2棵子树
所有叶子结点在同一层
K棵子树的分支节点存在K-1个关键字
关键字ceil(M/2) - 1 <= n <= M-1
出现原因
红黑树是一个二叉树,在磁盘中寻找结点需要进行更多次磁盘寻址
需要一些降低层高的数据结构
B Tree与B+ Tree
B Tree:所有节点均存储数据
B+ Tree:只有叶子节点存储数据,内节点只用于索引(存储key)
Red-Black Tree
Red-Black Tree用途
Nginx Timer时间管理:服务器高并发IO的keep alive方案
中序遍历:定时器将全部符合条件的结点都释放
线程、进程调度(CFS)
Epoll事件的组织
stl中的std::set和std::map
key-value
网络服务器长连接存放<id, fd>
结构
可以使用宏定义将红黑树的key-value和性质分离
#define RBTREE_ENTRY(name, type)\ struct name{ strcut type *right; \ struct type *left; \ struct type *parent; \ unsigned char color; \ } \
定时器实现
定时器目的
处理某些延后处理事件
常用于并发网络编程
实现方案
数据结构:红黑树、时间轮、最小堆
检测机制:timerfd(将定时器作为事件使用epoll)
定时器结点struct TimerNodeBase { time_t expire; // 触发时间; uint64_t id;};struct TimerNode : public TimerNodeBase { using Callback = std::function<void(const TimerNode &node)>; TimerNode(uint64_t id, time_t expire, Callback func) : func(std::move(func)) { this->expire = expire; this->id = id; } Callback func;};
定时器结构class Timer {public: // 返回当前时间 static i ...
Template
模板相关模板的实例化一个模板只有被使用到,才会被实例化,否则不会被实例化。对于一个实例化后的模板来说,未被调用的成员函数将不会被实例化,只有成员函数被使用时,C++标准才要求实例化他们。其原因,有两点:
空间和时间效率的考虑,如果模板类中有100个成员函数,对某个特定类型只有2个函数会被使用,针对另一个特定类型只会使用3个,那么如果将剩余的195个函数实例化将浪费大量的时间和空间。
使模板有最大的适用性。并不是实例化出来的每个类型都支持所有模板的全部成员函数所需要的运算符。如果只实例化那些真正被使用的成员函数的话,那么原本在编译期有错误的类型也能够得到支持。
可以明确的要求在一个文件中将整个类模板实例化:
template class Point3d<float>;
也可以显示指定实例化一个模板类的成员函数:
template float Point3d<float>::X() const;
或是针对一个模板函数:
template Point3d<float> operator+( const Point3d<float& ...
malloc源码解析
malloc源码解析
glibc2.35
内部结构heap/* A heap is a single contiguous memory region holding (coalesceable) malloc_chunks. It is allocated with mmap() and always starts at an address aligned to HEAP_MAX_SIZE. */typedef struct _heap_info{ mstate ar_ptr; /* Arena for this heap. */ struct _heap_info *prev; /* Previous heap. */ size_t size; /* Current size in bytes. */ size_t mprotect_size; /* Size in bytes that has been mprotected PROT_READ|PROT_WRITE. */ size_t ...