复习一下

上一篇博文 epoll原理深入分析 详细分析了 epoll 底层的实现原理,如果对 epoll 原理有模糊的建议先看一下这篇文章。那么本文就开始用 epoll 实现一个简单的 tcp server/client。

本文基于我的 github: https://github.com/smaugx/epoll_examples

epoll 实现范式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# create listen socket
int listenfd = ::socket();

# bind to local port and ip
int r = ::bind();


# create epoll instance and get an epoll-fd
int epollfd = epoll_create(1);

# add listenfd to epoll instance
int r = epoll_ctl(..., listenfd, ...);


# begin epoll_wait, wait for ready socket

struct epoll_event* alive_events = static_cast<epoll_event*>(calloc(kMaxEvents, sizeof(epoll_event)));

while (true) {
int num = epoll_wait(epollfd, alive_events, kMaxEvents, kEpollWaitTime);

for (int i = 0; i < num; ++i) {
int fd = alive_events[i].data.fd;
int events = alive_events[i].events;

if ( (events & EPOLLERR) || (events & EPOLLHUP) ) {
std::cout << "epoll_wait error!" << std::endl;
// An error has occured on this fd, or the socket is not ready for reading (why were we notified then?).
::close(fd);
} else if (events & EPOLLRDHUP) {
// Stream socket peer closed connection, or shut down writing half of connection.
// more inportant, We still to handle disconnection when read()/recv() return 0 or -1 just to be sure.
std::cout << "fd:" << fd << " closed EPOLLRDHUP!" << std::endl;
// close fd and epoll will remove it
::close(fd);
} else if ( events & EPOLLIN ) {
std::cout << "epollin" << std::endl;
if (fd == handle_) {
// listen fd coming connections
OnSocketAccept();
} else {
// other fd read event coming, meaning data coming
OnSocketRead(fd);
}
} else if ( events & EPOLLOUT ) {
std::cout << "epollout" << std::endl;
// write event for fd (not including listen-fd), meaning send buffer is available for big files
OnSocketWrite(fd);
} else {
std::cout << "unknow epoll event!" << std::endl;
}
} // end for (int i = 0; ...

}

epoll 编程基本是按照上面的范式进行的,这里要注意的是上面的反应的只是单进程或者单线程的情况。

如果涉及到多线程或者多进程,那么通常来说会在 listen() 创建完成之后,创建多线程或者多进程,然后再操作 epoll.

阅读全文 »

Epoll 的出现

想必能搜到这篇文章的,应该对 select/poll 有一些了解和认识,一般说 epoll 都会与 select/poll 进行一些对比,select、poll 和 epoll 都是一种 IO 多路复用机制。

select 的问题

select 的问题在于描述符的限制,能监控的文件描述符最大为 FD_SETSIZE,对于连接数很多的场景就无法满足;

另外select 还有一个问题是,每次调用 select 都需要从用户空间把描述符集合拷贝到内核空间,当描述符集合变大之后,用户空间和内核空间的内存拷贝会导致效率低下;

另外每次调用 select 都需要在内核线性遍历文件描述符的集合,当描述符增多,效率低下。

poll 的问题

由于 select 存在上面的问题,于是 poll 被提了出来,它能解决 select 对文件描述符数量有限制的问题,但是依然不能解决线性遍历以及用户空间和内核空间的低效数据拷贝问题。

epoll 是什么

select/poll 在互联网早期应该是没什么问题的,因为没有很多的互联网服务,也没有很多的客户端,但是随着互联网的发展,C10K 等问题的出现,select/poll 已经不能满足要求了,这个时候 epoll 上场了。

epoll 是 linux 内核 2.6 之后支持的,epoll 同 select/poll 一样,也是 IO 多路复用的一种机制,不过它避免了 select/poll 的缺点。下面详细讲解一下 epoll 反应堆的原理。

Epoll 反应堆

epoll 原理

要完整描述 epoll 的原理,需要涉及到内核、网卡、中断、软中断、协议栈、套接字等知识,本文尽量从比较全面的角度来分析 epoll 的原理

上面其实讨论了 select/poll 几个缺点,针对这几个缺点,就需要解决以下几件事:

  • 如何突破文件描述符数量的限制
  • 如何避免用户态和内核态对文件描述符集合的拷贝
  • socket 就绪后,如何避免线性遍历文件描述符集合
阅读全文 »

why wiki

博客通常是用来记录一些完整的文章,每篇文章有一个主题。但是我想把平日里的一些笔记也记录到我的博客里,但笔记是零散的,随时的,不是完整的一个主题。所以打算构建一个 wiki 页面,专门用来存放我的笔记,wiki 页面类似于 维基百科的形式。

我的博客采用的是 hexo 构建的,如果打算 DIY 一个类似于 维基百科 的 wiki 页面的话,对于我来说,也许有点难度,毕竟我只会写简单的网页。那么有没有现成的方案或者替代的方案呢?

答案是有的,那就是 mkdocs

mkdocs 使用

什么是 Mkdocs 呢?

MkDocs is a fast, simple and downright gorgeous static site generator that’s geared towards building project documentation. Documentation source files are written in Markdown, and configured with a single YAML configuration file. Start by reading the introduction below, then check the User Guide for more info.

mkdocs 是一个用 python 编写的静态站点生成工具,主要是用来编写项目文档,文档使用 Markdown 编写,只需要配合一个 YAML 配置文件,就能快速生成一个站点。

毫无疑问,对于我来说,它有以下几个优点:

  • 使用 python 编写(说明有 DIY 的可能)
  • 源文件使用 Markdown 编写
  • 只需要一个 Yaml 文件,非常简单了
  • 主题可选(当然目前来说不是特别多)

可以先看一下 我的wiki.

阅读全文 »

CDN

关于 CDN 是什么,我想应该不用做过多的介绍,毕竟现在是一个 “云” 的时代,你至少也听说过 阿里云 或者 腾讯云 吧,当然其中就包括 CDN 业务。

CDN 的作用有很多,比如可以用来加速网站的访问,可以用来防护网站等。本篇文章讨论的就是使用 cloudflare 作为 CDN 来加速博客网站,并让博客开启 https,提升博客安全等级。

  • 加速网站访问
  • 开启https

选择什么 CDN 呢?

选择 CDN,对于个人博客来说,主要考虑的还是访问速度以及价格,当然也有免费的 CDN。Cloudflare 就是一家提供免费 CDN 的公司,也是在 CDN 领域比较知名的公司。

话不多说,关于 cloudflare 的配置网上可以搜到很多文章,这里我就简单记录一下。

阅读全文 »

缘起

我的博客一直采用的是 github pages 来托管,中间断断续续的也没怎么管理过,偶尔写几篇博客,所以也就没怎么关心过访问速度,搜索引擎收录等问题。

不过我对博客一直还是情有独钟,我觉得像我一样的软件工程师,如果能有个人博客,并且保持一定程度的更新率还是很有必要的。

这次迁移主要考虑三个原因:

  • 访问速度较慢
  • 博客还不支持 https
  • 谷歌搜索引擎收录较少

github pages 服务器位于美国,对于中文博客来说,访问还是有一些慢的,且不说 github 未来在我国很有可能被 feng,所以打算迁移到国内来。之前博客其实是有部署过双线的,国外走 github,国内走 coding,但奈何 coding 不争气,后来我干脆停了 coding 的解析。现在打算找一个付费的香港虚拟主机,一年几十块钱搞定。

另外就是由于之前已经采用了 rebootcat.com 这个域名,所以无法在 github pages 上开启 https(当然方法是有的,比如使用 cloudflare 加速,这个详见我另外一篇博文),所以这次的迁移也打算开启全站 https。

阅读全文 »

前言

一直没有时间来整理下博客搭建的一些事情,现在补上一篇,给 Hexo Next 博客添加一个相册功能,使用瀑布流的方式。

原理说明

  • 使用 github 作为仓库存储图片文件(图床)
  • 使用 jsdelivr 进行图片 CDN 加速

优点

此种方式的优点是免费,不需要购买其他的对象存储产品;并且使用的是 github 作为图床,图片不会丢失。

早期的博文使用的是七牛云的免费存储,结果后来被他们删掉了。。。结果造成文中的一些图片链接都是 404,有兴趣的可以翻一翻我早期的博客。

缺点

由于采用的是 github 仓库存储图片,但是 github 对单仓库有 50MB 的大小限制,所以单仓库可能不能够存储太多的文件;

解决方法就是建立很多的图片仓库(稍微有点费劲,不过是行得通的);另外上传的单张图片大小最好不要太大。

还有个缺点就是得折腾啊,且看我后文。

各位可以参考下我的相册瀑布流: 摄影

开始搭建相册瀑布流

开始之前,需要简单介绍一下,我参考的是 Hexo NexT 博客增加瀑布流相册页面 这篇文章,文中涉及到的脚本主要都是 js 实现;与他不同的是,由于我对 js 的掌握远远不及我对 Python 的掌握,故部分脚本我采用了 Python 实现。

所以在开始操作之前,你可以根据自己的技能,选择不同的方式。如果你擅长 python,那么跟着我来吧。

阅读全文 »

对行业现状的一点看法

2020 年,新冠肆虐。

最近对于区块链的想法有点消极。简单谈一下。

纵观整个区块链行业,公链项目死了很多,还活着的也在拖着,除了少数明星公链。也许未来的几年之内,这种状况还会持续下去,对于公链项目来说,要么死,要么拖下去再死,要么成为明星。无论哪一条路,都异常难!

区块链目前能解决的问题范围依然还是比较局限,一方面受限于技术层面,一方面受限于政治层面。技术方面的难点,在于架构,在于算法设计,在于安全,在于通信。

架构上目前行业普遍追求可扩展的架构,这样的目的在于提高 TPS,为未来可能存在的真实大量业务提供服务,当然必然为此牺牲去中心化属性,牺牲安全属性,抉择就在于追求什么目标?从比特币到以太坊,再到 EOS,再到各种分片的公链,可以理解为逐步为了高 TPS 改良,因为比特币的交易速度实在是太慢了,为此我们势必要有一条满足我们交易需求的公链,至于这个交易频率需要多快,也许可以对标中心化得出答案。

比如 visa 的 TPS 在 1000 ~ 2000,银联在 2000 左右, paypal 600 ~ 1000等等。这里就不得不提出一个疑问,对于公链来说,追求高 TPS 是不是一个伪需求?

算法层面,为了保证零信任网络内部达成一致共识,会涉及到大量的收发包以及加解密过程,然而至今没有一条公链的共识算法能称得上权威或者标杆,整个行业仍然处于研究阶段,不同的公链之间互相参考学习,然后进行创新以及试验。

这个过程可能很漫长,需要大量的人才投入贡献。这也就意味着现阶段的公链,至少在共识算法层面,不能达到一个质的飞越。也许在未来,还得依靠其他的手段做改良。

阅读全文 »

前言

我是一个 linux c++ 开发者,但是一直对 Makefile 的语法很是头痛,每次都记不住,所以每次写 Makefile 都很痛苦,Makefile 里需要你自己编写依赖和推导规则,这个过程能不能简单点呢?

对于编译一个 C++ 工程来说,也许需要的就是头文件路径、库路径、编译参数,剩下的东西基本也不重要,这三样足够去编译一个工程了。所以有没有一个工具能简单点的去实现 C++ 项目的构建呢?

答案是有的,上一篇博文 scons构建C++项目 介绍了 使用 scons 来构建 C++ 项目,大大提高了编写构建脚本的效率,使用起来也极为方便,对于熟悉 python 的童鞋来说真的是大大的福音;但 scons 的问题就是在大型项目的时候构建起来可能会很慢(听说的)。那么有没有其他的工具呢?

当然有,cmake 就是这样的一个工具,既能满足跨平台的编译,并且屏蔽了 Makefile 蛋疼的语法,使用一种更加简单的语法编写构建脚本,用在大型项目也毫无压力。

当然,对于我个人来说,cmake 的使用还是有门槛的,刚接触 cmake 可能还是会被它的语法搞的头疼(cmake 的语法也还是挺折腾的)。但是别急,沉下心来,本篇博文就带你从 cmake 入门到编写一个复杂工程的实战。

CMake

什么是 cmake

这里直接引用官网的解释:

CMake is an open-source, cross-platform family of tools designed to build, test and package software. CMake is used to control the software compilation process using simple platform and compiler independent configuration files, and generate native makefiles and workspaces that can be used in the compiler environment of your choice. The suite of CMake tools were created by Kitware in response to the need for a powerful, cross-platform build environment for open-source projects such as ITK and VTK.

CMake 是一个开源的跨平台的构建工具,语法简单,编译独立,并且很多知名大型项目也在用 CMake,比如 KDE、Netflix 、ReactOS等。

阅读全文 »

前言

我是一个 linux c++ 开发者,但是一直对 Makefile 的语法很是头痛,每次都记不住,所以每次写 Makefile 都很痛苦,Makefile 里需要你自己编写依赖和推导规则,这个过程能不能简单点呢?

对于编译一个 C++ 工程来说,也许需要的就是头文件路径、库路径、编译参数,剩下的东西基本也不重要,这三样足够去编译一个工程了。所以有没有一个工具能简单点的去实现 C++ 项目的构建呢?

答案是有的,Scons 就是答案。

Scons

什么是 scons

这里直接引用官网的解释:

What is SCons?

SCons is an Open Source software construction tool—that is, a next-generation build tool. Think of SCons as an improved, cross-platform substitute for the classic Make utility with integrated functionality similar to autoconf/automake and compiler caches such as ccache. In short, SCons is an easier, more reliable and faster way to build software.

What makes SCons better?

  • Configuration files are Python scripts–use the power of a real programming language to solve build problems.
  • Reliable, automatic dependency analysis built-in for C, C++ and Fortran–no more “make depend” or “make clean” to get all of the dependencies. Dependency analysis is easily extensible through user-defined dependency Scanners for other languages or file types.
  • Built-in support for C, C++, D, Java, Fortran, Yacc, Lex, Qt and SWIG, and building TeX and LaTeX documents. Easily extensible through user-defined Builders for other languages or file types.
  • Building from central repositories of source code and/or pre-built targets.
  • Built-in support for fetching source files from SCCS, RCS, CVS, BitKeeper and Perforce.
  • Built-in support for Microsoft Visual Studio .NET and past Visual Studio versions, including generation of .dsp, .dsw, .sln and .vcproj files.
  • Reliable detection of build changes using MD5 signatures; optional, configurable support for traditional timestamps.
  • Improved support for parallel builds–like make -j but keeps N jobs running simultaneously regardless of directory hierarchy.
  • Integrated Autoconf-like support for finding #include files, libraries, functions and typedefs.
  • Global view of all dependencies–no more multiple build passes or reordering targets to build everything.
  • Ability to share built files in a cache to speed up multiple builds–like ccache but for any type of target file, not just C/C++ compilation.
  • Designed from the ground up for cross-platform builds, and known to work on Linux, other POSIX systems (including AIX, BSD systems, HP/UX, IRIX and Solaris), Windows NT, Mac OS X, and OS/2.

最大特点就是使用 Python 语法来编写编译构建脚本,并且支持依赖自动推导,支持编译 C/C++/D/Java/Fortran等项目,并且是跨平台的(因为 python 是跨平台的)。

阅读全文 »

aliyun_spot

自动创建阿里云抢占式实例。

支持一下作者,购买阿里云

背景

阿里云抢占式实例应该属于阿里云的一种闲置资源利用,性价比非常高,每小时的价格在 0.01 ~ 0.05 每小时,具体根据不同的配置和地域有差别,流量价格小于 1元/G.

抢占式实例最高可以以一折的价格购买 ECS 实例,并能稳定持有该实例至少一个小时。一个小时后,当市场价格高于您的出价或资源供需关系变化时,抢占式实例会被自动释放,请做好数据备份工作。

非常适合爬虫

非常适合爬虫

非常适合爬虫

也适合程序员个人日常开发使用,上班来创建,下班释放,开销基本可以控制在在 1毛 ~ 2 毛。

对于我来说,最近在写一个爬虫,看了很多代理都很贵,免费的又不稳定,正好了解到阿里云的抢占式实例,所以非常满足我的需求。

但是要注意,这个实例是有可能被释放的,但是不用担心,比如香港地区的释放率最近(2020-08-19)小于 3%. 另外,每个人可以最大创建 100 个实例,所以还是不用太担心。

阅读全文 »