- 博客(15)
- 收藏
- 关注
原创 static在类中的使用
静态类型,是与类本身相关联,属于类本身,而不是属于类创建的某个实例(对象),不与类对象关联,所有的类实例共享同一份静态成员变量。this。
2024-10-17 22:11:47 361
原创 并发三剑客async、future、promise以及线程池实现
有一点,这里直接手动封装异步操作嘛,可能某个值在异步操作很早就得到了,可以不必等待整个异步操作完成,就可以把数据存在promise中,然后外部关联的future可以直接获取数据,也就是说,如果外部调用future::get(),只需要阻塞等待到数据存在promise中后,就会立即获取,继续执行下面的程序。与上面async的区别是,它可以先包装一个可以异步执行的任务,然后将其与future关联,等待需要的时候,手动创建一个线程去执行这个异步事件,更加灵活。是一个用于异步执行函数的模板函数,它返回一个。
2024-10-16 00:54:20 598
原创 写一个简单的异步服务器(应答)
分为两个模块,session和server。session用于通信会话,为其创建一个socket用于通信,异步读与异步写操作;server开始准备工作,绑定端口,开启监听模式,调用异步accept,在后台监听嘛,当收到客户端的请求时,接受请求,并回调accept处理函数。由handle_accept内部调用session的start,将异步读这个事件放入后台内部事件循环中,等待条件满足了就会调度执行并调用回调函数,异步读再调用异步写,异步写再调用异步读,就这样一应一答模式。
2024-10-11 00:09:06 1028
原创 buffer结构、同步读写API与简单的同步读写服务器
1.同步读写缺陷在于阻塞,如果客户端不发送数据会导致服务端一直阻塞在read操作,这将导致服务器处于阻塞等待状态。2.在这个demo中,通过开辟新的线程为新生成的连接处理读写,但是一个进程开辟的线程是有限的,约为2048个线程,在Linux环境可以通过unlimit增加一个进程开辟的线程数,但是线程过多也会导致切换消耗的时间片较多。3.该服务器和客户端为应答式,实际场景为全双工通信模式,发送和接收要独立分开。
2024-10-10 21:33:46 656
原创 boost::asio之socket的创建和连接
服务器和客户端的通信流程大致如下:是一种用于网络通信的编程接口,它提供了一种机制,使不同主机上的进程能够通过网络进行数据交换。
2024-10-10 21:27:59 846
原创 异步读写API
首先,我们定义一个session类,这个session类表示服务器处理客户端连接的管理类对端的连接读写,封装了Connect函数在读写操作前,我们先封装一个Node结构,用来管理要发送和接收的数据,该结构包含数据域首地址,数据的总长度,以及已经处理的长度(已读的长度或者已写的长度)写了两个构造函数,第一个构造函数的两个参数负责构造写节点,第二个构造函数负责构造读节点。
2024-10-07 19:56:16 749
原创 在线程间共享数据:互斥与死锁
竞争状态:多线程同时读写共享数据临界区:读写共享数据的代码片段,对于共享数据同时只能有一个线程访问防止恶性条件竞争: 1)坑(死锁)示例 ②避免长时间死锁 1.try_lock() 是一种非阻塞的锁获取方式。如果锁当前不可用(即已被其他线程持有),它将立即返回,而不会等待 2.timed_mutex.try_lock_for() 超时锁 也是一种非阻塞的锁获取方式,如果当前锁不可用,等待一个指定的时间段后,再返回
2024-09-24 00:21:48 637
原创 三大函数:拷贝构造、拷贝赋值、析构
含有指针的class,以string为例大致框架:分析:String:一般在设计字符串时,对字符串的设计都是这样设计,让字符串里拥有一个指针,在需要内存的时候才创建(分配)空间放另一个字符串本身。因为这样可以根据字符串动态分配空间,而不是在类里放一个数组。例如下面,封装简单字符串:2.对class里的函数进行定义以下面这个例子,进行讲解:String s1();String s2(“hello”);分别调用构造函数。当将字符串经动态分配存进String后,在对象要死亡前,需要将new的
2023-11-09 01:45:21 105 1
原创 堆(手写堆模拟)
堆:满足一个性质,这里以小根堆为例,它的每一个节点都是小于对于它的左右儿子的。④.删除任意一个元素 //假如是k,heap[k] = heap[size];用一维数组存,初始位置存根节点,每个节点x的左儿子是2x,右儿子2x+1. (这里的是指的数组下标)③.删除最小值 //删除就用最后一个元素覆盖到堆顶元素,size--,然后再down操作。除了最后一层节点外,树上面的节点都是满的,不存在空节点,最后一层从左到右排列。,从倒数第二层最后一个元素n/2(向下取整)开始向上遍历,不断的down。
2023-08-15 22:23:45 82
原创 【无标题】
在这些示例中,`getArray()` 函数返回了一个包含两个整数的 `std::array<int, 2>` 对象,并使用初始化列表 `{i, j}` 进行构造。而 `getVector()` 函数返回一个包含两个整数的 `std::vector<int>` 对象,并同样使用初始化列表 `{i, j}` 进行构造。该数组包含了 `i` 和 `j` 两个整数。使用 `std::array` 或 `std::vector` 来返回数组会更加安全、简洁,并且消除了手动内存管理的麻烦。这里涉及到一些知识点,
2023-08-12 10:12:49 83 1
原创 单调栈和单调队列及经典模型
以最小值为例,和单调栈差不多,每一次入队时x都要先去和队尾判断一下是否逆序,若没有逆序则x入队;思路:可以用队列q[N]去维护,暴力做法就是,队列中始终放k个元素,窗口每滑动一次,就遍历一下队列,输出最小值。分析:按照常规解题思路,可以用暴力+双指针两层循环遍历,但这样的解法遇到数据大的就会超时。单调栈是一个元素严格满足单调性的栈。例如,找出每个数左边离它最近的比它小的数。找出每个数左边离它最近的比它大或小的数。满足栈的后进先出特性,(栈是。单调队列:即单调递减或单调递增的。以例题的形式来谈谈单调队列(
2023-07-18 03:44:04 89 1
原创 string未能成功赋值的原因
我在创建`new_p`字符串时没有分配足够的空间,当你尝试给每个字符串赋值时,其实是在访问一个未分配内存的位置,这会导致未定义的行为。可以使用`push_back()`函数向字符串末尾添加字符,字符串对象会自动扩展以容纳新的字符,并确保内存分配正确。自己调试了好久,发现在输出时直接跳过p数组,p数组输出时没用任何东西,然后我就改,刚开始以为是我赋值出错的原因,然后把else后面的内容用for循环遍历赋值,发现还是没变化,就意识到是string p;定义时出了问题,然后查了资料才知道。
2023-07-06 02:44:50 874
原创 bfs广度优先搜索(插入知识点利用C++标准库中的队列模板、C++值STL库的pair用法)
(又称广度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。G 的每个格子要么是道路,要么是障碍物(道路用 . 表示,障碍物用 * 表示)已知迷宫的入口位置为 设为S,出口位置为 T。(这个的意义就是我们每次调用front()和pop()之前,都要检查一下,保证队列不为空,否则在去访问队列首部或者让其出队时若是空队列,则会发生错误)好了,进入正题,由下面的题解代码细细体会pair的妙处吧,对于下面代码中。
2023-07-04 02:46:23 329
原创 栈和队列(插入两个知识点:isdigit( ) 函数、unordered_map与map不同之处)
4. 支持的操作:unordered_map和map都提供了类似的成员函数和操作符,例如插入insert、删除erase、查找find等。然而,在某些特殊情况下,哈希函数可能导致unordered_map的性能下降,而红黑树保持了较稳定的性能。3. 效率:在大多数情况下,unordered_map的查找、插入和删除操作的平均时间复杂度为。功能:当判断的字符是数字时,函数返回1~9的非零值,当判断的字符不是数字时,函数返回 0。难点在于这样判断运算符的优先级 ,没想出来,参考了一位大佬的思路,详情见。
2023-07-02 23:22:39 163 1
原创 dfs经典例题——n皇后、数的排列
当所有位置都尝试完毕且无法找到合适的位置时,所有循环都结束,函数执行到最后一行`return`语句之后,会返回到上一次递归调用的地方,不断回溯,直到搜完所有可能找到最终结果。这道题限制条件有三个,对于对角线,由数学知识(可以自己画个图像)知正对角线横纵坐标相减为定值,即x-y,考虑到数组下标不能为负数,所以x-y+n;暴力枚举来搜索,每一行只能有一个皇后,就先按行再按列来枚举,列举每一种情况,即n*n种情况,怎样筛选结果呢,见下面代码(代码我是参考别人的,不是原创哈,自己写一遍理解一下)
2023-07-01 13:04:30 114 1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人