自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 设计模式-面向对象设计原则

变化使复用的天敌,面向对象设计最大的优势在于抵御变化面向对象设计原则1、依赖倒置原则高层模块(稳定)不应该依赖于底层模块(变化),二者都应依赖于抽象(稳定)抽象(稳定)不应该依赖于实现细节(变化),实现细节应该依赖于抽象(稳定)2、开闭原则对扩展开放,对更改封闭类模块应该是可扩展的,但是不可修改的3、单一职责原则一个类应该仅有一个引起它变化的原因变化的方向隐含着类的责任比如一个类有很多很多的方法,很很多很多的功能,这就不正常。意味着类的责任太多4、Liskov替换原则

2022-04-01 14:51:52 301

原创 Redis学习笔记38——通信开销:限制Redis Cluster规模的关键因素

Redis Cluster 能保存的数据量以及支撑的吞吐量,跟集群的实例规模密切相关。Redis 官方给出了 Redis Cluster 的规模上限,就是一个集群运行 1000 个实例。为何要限制集群规模呢?因为,实例间的通信开销会随着实例规模增加而增大,在集群超过一定规模时(比如 800 节点),集群吞吐量反而会下降。所以,集群的实际规模会受到限制。实例通信方法对集群规模的影响Redis Cluster 在运行时,每个实例上都会保存 Slot 和实例的对应关系(也就是 Slot 映射表),以及自身

2021-07-15 20:01:57 655 2

原创 Redis学习笔记37——数据分布优化:如何应对数据倾斜

在切片集群中,数据会按照一定规则分布在不同的实例上进行保存。但是这很容易导致一个问题:数据倾斜。数据倾斜分为两种:数据量倾斜:在某些情况下,实例上的数据分布不均衡,某个实例上的数据特别多。数据访问倾斜:虽然每个集群实例上的数据量相差不大,但是某个实例上的数据是热点数据,被访问得非常频繁。数据量倾斜成因当数据量倾斜发生时,数据在切片集群的多个实例上分布不均衡,大量数据集中到了一个或几个实例上这主要有三个原因:在某个实例上保存了 bigkeySlot 分配不均Hash Tagbig

2021-07-15 17:19:00 688

原创 Redis学习笔记36——Redis支撑秒杀场景的关键技术和实践都有哪些

秒杀场景包含了多个环节,可以分成秒杀前、秒杀中和秒杀后三个阶段,每个阶段的请求处理需求并不相同,Redis 并不能支撑秒杀场景的每一个环节。秒杀场景的负载特征对支撑系统的要求第一个特征是瞬时并发访问量非常高一般数据库每秒只能支撑千级别的并发请求,而 Redis 的并发处理能力(每秒处理请求数)能达到万级别,甚至更高。所以,当有大量并发请求涌入秒杀系统时,我们就需要使用 Redis 先拦截大部分请求,避免大量请求直接发送给数据库,把数据库压垮。第二个特征是读多写少,而且读操作是简单的查询操作在秒杀场

2021-07-15 11:43:35 338

原创 Redis学习笔记35——Codis VS Redis Cluster:我该选择哪一个集群方案?

Codis组件Codis 集群包含 codis server、codis proxy、Zookeeper、codis dashboard 和 codis fe 这四大类组件。我们再来回顾下它们的主要功能。codis proxy 和 codis server 负责处理数据读写请求,其中,codis proxy 和客户端连接,接收请求,并转发请求给 codis server,而 codis server 负责具体处理请求。codis dashboard 和 codis fe 负责集群管理,其中,cod

2021-07-15 11:05:09 569 1

原创 Redis学习笔记33——脑裂:奇怪的数据丢失

所谓的脑裂,就是指在主从集群中,同时有两个主节点,它们都能接收写请求。而脑裂最直接的影响,就是客户端不知道应该往哪个主节点写入数据,结果就是不同的客户端会往不同的主节点上写入数据。而且,严重的话,脑裂会进一步导致数据丢失。为什么会发生脑裂第一步在主从集群中发生数据丢失,最常见的原因就是主库的数据还没有同步到从库,结果主库发生了故障,等从库升级为主库后,未同步的数据就丢失了。如果是这种情况的数据丢失,我们可以通过比对主从库上的复制进度差值来进行判断,也就是计算 master_repl_offset 和

2021-07-14 20:29:47 277 1

原创 Redis歇息笔记32——主从切换与故障切换的问题

主从数据不一致为什么会出现这个问题?因为主从库间的复制命令是异步的。具体来说,在主从库命令传播阶段,主库收到新的写命令后,会发送给从库。但是,主库并不会等到从库实际执行完命令后,再把结果返回给客户端,而是主库自己在本地执行完命令后,就会向客户端返回结果了。如果从库还没有执行主库同步过来的命令,主从库间的数据就不一致了。那在什么情况下,从库会滞后执行同步命令呢?其实,这里主要有两个原因。主从库间的网络可能会有传输延迟即使从库及时收到了主库的命令,但是,也可能会因为正在处理其它复杂度高的命令(例如集

2021-07-14 19:18:03 732 1

原创 Redis学习笔记30——如何使用Redis实现分布式锁?

以前使用过的锁都是本地锁,但是,Redis 属于分布式系统,当有多个客户端需要争抢锁时,我们必须要保证,这把锁不能是某个客户端本地的锁。否则的话,其它客户端是无法访问这把锁的,当然也就不能获取这把锁了。所以,在分布式系统中,当有多个客户端需要获取锁时,我们需要分布式锁。此时,锁是保存在一个共享存储系统中的,可以被多个客户端共享访问和获取。Redis 本身可以被多个客户端共享访问,正好就是一个共享存储系统,可以用来保存分布式锁。和单机上的锁类似,分布式锁同样可以用一个变量来实现。客户端加锁和释放锁的操作逻

2021-07-13 22:28:59 128

原创 Redis学习笔记29——无锁的原子操作:Redis如何应对并发访问

为了保证并发访问的正确性,Redis 提供了两种方法,分别是加锁和原子操作。但是加锁会遇到两个问题:首先是加锁操作过多会降低系统的并发访问性能其次,Redis客户端要加锁时,需要使用分布式锁,而分布式锁实现复杂原子操作是另一种提供并发访问控制的方法,实现了无锁操作。既可以保证并发控制,还能减少系统对并发性能的影响。并发访问中需要对什么进行控制?当客户端需要修改数据时,基本流程分成两步:客户端先把数据读取到本地,在本地进行修改;客户端修改完数据后,再写回 Redis。即为“读取 -

2021-07-13 16:23:08 335

原创 Redis学习笔记28——Pika:如何基于SSD实现大容量Redis

着业务数据的增加,就需要 Redis 能保存更多的数据。你可能会想到使用 Redis 切片集群,把数据分散保存到多个实例上。但是这样做的话,会有一个问题,如果要保存的数据总量很大,但是每个实例保存的数据量较小的话,就会导致集群的实例规模增加,这会让集群的运维管理变得复杂,增加开销。如果增加单个实例的内存容量,但是在实例恢复,主从同步过程中会引起恢复时间增长、主从切换开销大、缓冲区容易溢出。可以使用基于SSD来实现大容量的Redis实例,即Pika键值数据库。Pika有两个特点:单实例可以保存大容量数

2021-07-13 12:48:20 799

原创 Redis学习笔记27——缓存被污染了怎么办

在一些场景下,有些数据被访问的次数非常少,甚至只会被访问一次。当这些数据服务完访问请求后,如果还继续留存在缓存中的话,就只会白白占用缓存空间。这种情况,就是缓存污染。我们应用 Redis 缓存时,如果能缓存会被反复访问的数据,那就能加速业务应用的访问。但是,如果发生了缓存污染,那么,缓存对业务应用的加速作用就减少了。如何解决缓存污染问题我们很容易就可以想到了各种缓存淘汰策略,那这些策略的效果如何?如果这8种策略(noeviction、volatile-random、volatile-ttl、vola

2021-07-13 00:33:16 119

原创 Redis学习笔记26——缓存异常:如何解决缓存雪崩、击穿、穿透问题?

缓存雪崩缓存雪崩是指大量的应用请求无法在 Redis 缓存中进行处理,紧接着,应用将大量请求发送到数据库层,导致数据库层的压力激增。缓存雪崩一般有两个原因导致:1、缓存中有大量数据同时过期解决方法:(1)增加较小的随机数避免给大量相同的数据设置相近的过期时间,如果业务确实需要同时失效,可增加一个较小的随机数(1~3分钟)(2)服务降级发生缓存雪崩时,针对不同的数据采取不同的处理方式。如果对于非核心数据,则暂停从缓存中查询这些数据,直接返回与定义信息、空值或是错误信息;对于访问核心数据,则仍然

2021-07-12 22:29:40 162

原创 Redis学习笔记25——缓存异常:如何解决缓存和数据库的数据不一致问题?

缓存和数据库的数据不一致是如何发生的?一致性包含了两种情况:缓存中有数据,那么,缓存的数据值需要和数据库中的值相同;缓存中本身没有数据,那么,数据库中的值必须是最新值。发生的原因也可以分成两类:在更新数据库或更新缓存的过程中,其中一个失败的情况高并发状态下,更新数据库或更新缓存这两个操作之间,有其他线程的并发读操作,导致其他线程读到旧值1、更新数据库或Redis有一个失败当缓存的读写模式不同时,缓存数据不一致的发生情况不一样,我们的应对方法也会有所不同,所以,我们先按照缓存读写模式,

2021-07-12 21:30:38 328

原创 Redis学习笔记24——替换策略:缓存满了怎么办

如果把所有的数据都放入缓存是否很好?并不,根据“八二原理”,80% 的请求实际只访问了 20% 的数据,所以全部放入缓存的性价比很低。解决这个问题就涉及到缓存系统的一个重要机制,即缓存数据的淘汰机制。简单来说,数据淘汰机制包括两步:第一,根据一定的策略,筛选出对应用访问来说“不重要”的数据;第二,将这些数据从缓存中删除,为新来的数据腾出空间。设置多大的缓存合适?根据“八二原理”,也就是把缓存空间容量设置为总数据量的 20% 的话,就有可能拦截到 80% 的访问。但只是有可能,具体情况还是需要根据业务

2021-07-12 17:41:32 174

原创 Redis学习笔记23——旁路缓存:Redis是如何工作的?

计算机系统中,默认有两种缓存:CPU 里面的末级缓存,即 LLC,用来缓存内存中的数据,避免每次从内存中存取数据;内存中的高速页缓存,即 page cache,用来缓存磁盘中的数据,避免每次从磁盘中存取数据。跟内存相比,LLC 的访问速度更快,而跟磁盘相比,内存的访问是更快的。所以,我们可以看出来缓存的第一个特征:在一个层次化的系统中,缓存一定是一个快速子系统,数据存在缓存中时,能避免每次从慢速子系统中存取数据。对应到互联网应用来说,Redis 就是快速子系统,而数据库就是慢速子系统了。我们..

2021-07-09 15:40:12 305

原创 Redis学习笔记21——缓冲区:一个可能引发“惨案”的地方

缓冲区的功能其实很简单,主要就是用一块内存空间来暂时存放命令数据,以免出现因为数据和命令的处理速度慢于发送速度而导致的数据丢失和性能问题。但如果写入速度持续大于读取速度,则缓冲区必然溢出。能否无限制的扩大缓冲区?显然不行,因为缓冲区处于内存,而Redis也在内存中,如果持续扩大缓冲区,很可能导致内存空间不足,从而使得Redis实例崩溃。在cs架构中,Redis与客户端进行通信之间需要输入缓冲区暂存客户端发送的命令数据,以及输出缓冲器暂存服务器返回给客户端的数据结果。此外,在主从节点间进行数据同步时

2021-07-08 22:30:50 281

原创 Redis学习笔记20——删除数据后,为什么内存占用率还是很高?

在使用 Redis 时,或许会遇到这样一个问题:明明做了数据删除,数据量已经不大了,为什么使用 top 命令查看时,还会发现 Redis 占用了很多内存呢?实际上,这是因为,当数据删除后,Redis 释放的内存空间会由内存分配器管理,并不会立即返回给操作系统。所以,操作系统仍然会记录着给 Redis 分配了大量内存。但是,由于Redis释放的内存空间可能不是连续的,所以无法保存较大的数据。这将减少Redis能够保存的实际数据量,也会降低Redis运行机器的成本回报率。内存碎片是如何形成的内因:内存分

2021-07-08 21:06:27 268 1

原创 Redis学习笔记18、19——波动的响应延迟:如何应对变慢的Redis

总的来说,从三个方面考虑:问题认定系统排查应对方案一、Redis真的变慢了么最直接的方案就是查看Redis的响应延迟redis-cli --latency -h host -p port如果大部分时候Redis延迟很低,而偶尔会出现几秒甚至几十秒的延迟,这基本可以断定Redis变慢了这种办法是看延迟的绝对值,但是由于不同的软硬件环境下,其延迟时间并不相同。所以还需要通过当前环境下的Redis基线性能做判断。从 2.8.7 版本开始,redis-cli命令提供了--intrinsic-

2021-07-06 00:16:57 401

原创 记录一次使用GDB调试coredump

出现了段错误:决定使用GDB查看是哪里的问题1、使用ulimit -c unlimited修改core文件的最大限制为无限(默认为0)2、使用-g重新编译文件3、正常运行,4、运行到上一次出错的地方,出现core dumped5、查看是否生成core文件6、使用 gdb + 可执行文件名 + core的方式调试7、显示结果显示这里出现了错误,但这明显是系统调用中的代码,所以接着查看递归栈8、使用bt查看递归栈从下往上看,很容易找到错误的地方之后发现是一个变量重复定义导

2021-06-23 09:37:39 165

原创 Redis学习笔记——异步机制:如何避免单线程模型的阻塞?

Redis 的网络 IO 和键值对读写是由主线程完成的,如果在主线程上执行的操作消耗的时间太长,就会引起主线程阻塞。但是,Redis 既有服务客户端请求的键值对增删改查操作,也有保证可靠性的持久化操作,还有进行主从复制时的数据同步操作,等等。操作这么多,究竟哪些会引起阻塞呢?Redis实例有哪些阻塞点与Redis交互的对象及其操作:客户端:网络 IO,键值对增删改查操作,数据库操作;磁盘:生成 RDB 快照,记录 AOF 日志,AOF 日志重写;主从节点:主库生成、传输 RDB 文件,从库接收

2021-06-23 00:35:55 247 1

原创 ubuntu下安装mysql以及ubuntu下安装mysql.h

安装mysqlubuntu16下安装mysql安装mysql.h安装mysql:sudo apt-get install mysql-server mysql-client安装开发包:sudo apt-get install libmysql++-dev我在安装时出现了找不到包的错误先后试了更新源、 升级的方法,才可以安装成功sudo apt-get update或sudo apt-get upgrade...

2021-06-22 15:28:02 649

原创 Redis学习笔记——消息队列的考验:Redis有哪些解决方案?

现在的互联网应用基本上都是采用分布式系统架构进行设计的,而很多分布式系统必备的一个基础软件就是消息队列。消息队列要能支持组件通信消息的快速读写,而 Redis 本身支持数据的高速访问,正好可以满足消息队列的读写性能需求。不过,除了性能,消息队列还有其他的要求,所以,很多人都很关心一个问题:“Redis 适合做消息队列吗?”消息队列的消息存取需求我先介绍一下消息队列存取消息的过程。在分布式系统中,当两个组件要基于消息队列进行通信时,一个组件会把要处理的数据以消息的形式传递给消息队列,然后,这个组件就可以

2021-06-22 01:04:48 182

原创 Redis学习笔记——如何在Redis中保存时间序列数据?

时间序列数据的特点如:设备 ID、压力、温度、湿度,这些与发生时间相关的一组数据,就是时间序列数据。这些数据的特点是没有严格的关系模型,记录的信息可以表示成键和值的关系(例如,一个设备 ID 对应一条记录),所以,并不需要专门用关系型数据库(例如 MySQL)来保存。而 Redis 的键值数据模型,正好可以满足这里的数据存取需求。写特点在实际应用中,时间序列数据通常是持续高并发写入的,例如,需要连续记录数万个设备的实时状态值。同时,时间序列数据的写入主要就是插入新数据,而不是更新一个已存在的数据,也就

2021-06-22 00:18:02 274

原创 Redis学习笔记—— 有一亿个keys要统计,应该用哪种集合?

要想选择合适的集合,我们就得了解常用的集合统计模式。集合类型常见的四种统计模式,包括聚合统计排序统计二值状态统计基数统计聚合统计所谓的聚合统计,就是指统计多个集合元素的聚合结果,比如求交集、并集、差集当你需要对多个集合进行聚合计算时,Set 类型会是一个非常不错的选择。不过,这里有一个潜在的风险。Set 的差集、并集和交集的计算复杂度较高,在数据量较大的情况下,如果直接执行这些计算,会导致 Redis 实例阻塞。所以,我们可以从主从集群中选择一个从库,让它专门负责聚合计算,或者是把数据

2021-06-18 01:29:52 217

原创 Redis学习笔记——万金油string为什么不好用了?

为什么string不好用了首先string太大了在Redis中,保存一个string需要使用64字节。如果要保存一个long型整数,原数据只有8字节,而却需要八倍的空间去存储它,这在保存大量数据时时非常不划算的。为什么需要用的64字节的空间?因为string不光有自身数据,还有一些“辅助”数据,比如自身的长度以及所占空间,这两个分别需要4字节,目前需要16字节。这些数据称为简单动态字符串(Simple Dynamic String,SDS)而这之外还需要“包裹一层”RedisObject,由元数

2021-06-18 01:16:14 339 1

原创 /bin/sh: 1: ctags: not found

今天安装webbench的时候发生了错误:这里有一句/bin/sh: 1: ctags: not found意思是说缺少ctags命令,我没有装,运行以下命令即可:sudo apt-get install ctags之后顺利安装

2021-06-17 18:58:20 1606

原创 Redis中的哨兵机制

主库挂了,如何不间断服务?这时会遇到三个问题:主库真的挂了么该选择哪个从库作为主库怎么把新主库的相关信息通知给主库和客户端采用哨兵机制哨兵机制基本流程哨兵其实就是一个运行在特殊模式的一个Redis进程。负责三个任务:监控、选主、通知。监控哨兵会周期性的给所有主从库发送ping命令,如果从库不通,则将其标记为“主观下线”;而如果是主库不通,则不可以这么武断。因为如果发生误判,启动了主从切换,后续的选主和通知操作都会带来额外的计算和通信开销。如果检测的是从库,那么,哨兵简单地把它标记为“主

2021-06-16 01:08:31 113

原创 libevent的“hello world”

#include <sys/signal.h>#include <event.h>void signal_cb(int fd, short event, void* argc) { struct event_base* base = (event_base*) argc; struct timeval delay = {2, 0}; printf("Caught an interrupt signal; exiting cleanly in two se

2021-06-04 23:14:23 215

原创 The program ‘make‘ can be found in the following packages

make的时候遇到The program 'make' can be found in the following packages: * make * make-guileTry: apt install <selected package>运行sudo apt-get install build-essential可解决

2021-06-04 20:33:38 250

原创 安装libevent

下载官方网站:http://libevent.org/,目前最新版是2.1.12下载压缩包名为 libevent-2.1.12-stable.tar.gz解压tar -zxvf libevent-2.1.12-stable.tar.gz 配置安装路径cd libevent-2.1.12-stable./configure -prefix=/usropenssl的安装在配置的时候提示需要安装opensslLinux系统安装openssl的两种方法编译安装makemake inst

2021-06-04 20:32:35 278

原创 时间堆定时器

前面讨论的定时方案都是以固定的频率调用心搏函数tick,并在其中依次检测到期的定时器,然后执行到期定时器上的回调函数。设计定时器的另外一种思路是:将所有定时器中超时时间最小的一个定时器的超时值作为心搏间隔。这样,一旦心搏函数tick被调用,超时时间最小的定时器必然到期,我们就可以在tick函数中处理该定时器。然后,再次从剩余的定时器中找出超时时间最小的一个, 并将这段最小时间设置为下一次心搏间隔。如此反复,就实现了较为精确的定时。最小堆很适合处理这种定时方案。由于最小堆是一种完全二叉树,所以我们可以用数

2021-06-04 17:03:20 191

原创 时间轮定时器

时间轮使用哈希的思想,将定时器散列到不同的链表上上图所示的时间轮内,(实线)指针指向轮子上的一个槽(slot)。它以恒定的速度顺时针转动,每转动一步就指向下一个槽(虚线指针指向的槽),每次转动称为一个滴答(tick)。一个滴答的时间称为时间轮的槽间隔si(slot interval),它实际上就是心跳时间。该时间轮共有N个槽,因此它运转一周的时间是N∗siN * siN∗si。每个槽指向一条定时器链表,每条链表上的定时器具有相同的特征:他们的定时时间相差N∗siN * siN∗si的整数倍。时间轮正是利

2021-06-04 15:52:11 408

原创 SIGALRM信号设置定时器

alarm和setitimer函数设置的实时闹钟,一旦超时,将触发SIGALRM信号(只触发一次)。因此我们可以利用该信号的信号处理函数来处理定时任务。但是如果要处理多个定时任务,我们就需要不断的触发SIGALRM信号,并在其信号处理函数中执行到期的任务。一般而言,SIGALRM信号按照固定的频率生成,即由alarm或setitmer函数设置的定时周期T保持不变。这里我们将通过一个实例——处理非活动链接,来介绍SIGALRM信号定时。并且使用一种简单的定时器实现——基于升序链表的定时器lst_tim

2021-06-03 22:24:54 1112

原创 使用socket选项SO_RCVTIMEO和SO_SNDTIMEO设置超时时间

socket选项SO_RCVTIMEO和SO_SNDTIMEO,他们分别 用来设置socket接受 / 发送数据超时时间。因此,这两个选项仅对数据接收和发送相关的socket专用系统调用有效(send、sendmsg、recv、recvmsg、accept、connect)在程序中,我们可以根据系统调用的返回值以及errno来判断超时时间是否已到,进而决定是否开始处理定时任务。下例为设置connect超时时间:#include <sys/types.h>#include <sys

2021-06-03 19:13:12 3600 1

原创 使用SIGURG信号发送接收带外数据

在Linux环境下,内核通知应用程序带外数据到达主要有两种方法:IO复用技术,select等系统调用在接收到带外数据时将返回,并向应用程序报告socket上的异常事件。使用SIGURG信号服务端:#include <sys/socket.h>#include <sys/types.h>#include <netinet/in.h>#include <arpa/inet.h>#include <assert.h>#include

2021-06-03 17:20:43 503

原创 信号、IO复用与统一事件源

信号是一个异步事件:信号处理函数和程序的主循环是两条不同的执行路线。很显然,信号处理函数需要尽可能快的执行完毕,以确保该信号不会被屏蔽太久(为了避免一些竞态条件,信号在处理期间,系统不会再次触发它)。一种典型的解决方案是:把信号的主要处理逻辑放到程序的主循环中,当信号处理函数被触发时,它只是简单地通知主循环程序接收到信号,并把信号值传递给主循环,主循环再根据接受到的信号值执行目标信号对应的逻辑代码。信号处理函数通常使用管道来将信号“传递”给主循环:信号处理函数往管道的写端写入信号值,主循环则从管道的读端

2021-06-03 16:21:55 116

原创 同时处理TCP、UDP的服务

我们讨论的服务器程序都只能监听一个端口。在实际应用中,有不少服务器程序能同时监听多个端口。从bind系统调用来看,一个socket只能和一个socket地址绑定,即一个socket只能用来监听一个端口。因此服务器如果要同时监听多个端口,就必须创建多个socket,并将它们分别绑定到各个端口上。这样就可以使用IO复用技术。另外,即使是同一个端口,如果服务器要同时处理该端口上的TCP、UDP请求,也需要创建两个不同的socket:一个是流socket,一个是数据报socket,并将它们都绑定在该端口上。#

2021-06-03 04:03:00 565

原创 非阻塞connect

connect出错时有一种值EINPROGRESS。这种错误发生在对非阻塞的socket调用connect,而连接又没有立即建立时。这种情况下,我们可以调用select、poll等函数来监听这个连接失败的socket上的可写事件。当select、poll等函数返回后,再利用getsockopt来读取错误码并清除该socket上的错误。如果错误码是0,表示连接成功建立,否则连接失败。通过这种非阻塞connect方式,我们就能同时发起多个连接并一起等待。#include <sys/types.h&g

2021-06-03 02:18:32 668

原创 EPOLLONESHOT事件

即使我们使用ET模式,一个socket上的某个事件还是可能被触发很多次。这在并发程序中就会引起一个问题。比如一个线程或进程在读取完某个socket上的数据后开始处理这些数据,而在数据的处理过程中该socket上又有新数据可读(EPOLLIN再次被触发),此时另外一个工作线程被唤醒来读取这些新的数据。于是就出现了两个线程同时操作一个我创可贴的局面。这并不是我们期望的。我们期望一个socket连接在任意时刻都之辈一个线程处理。这一点可以使用epoll中的EPOLLONESHOT事件实现。对于注册了EPOLLO

2021-06-03 01:12:01 459 2

原创 epolloneshot_test.cpp:(.text+0x582): undefined reference to `pthread_create‘

编译指令需要在尾部加上-lpthread,如下:g++ -o epolloneshot_test epolloneshot_test.cpp -lpthread

2021-06-03 00:57:04 152

空空如也

空空如也

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

TA关注的人

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