<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[Tanswer_]]></title><description><![CDATA[纸上得来终觉浅，绝知此事要躬行]]></description><link>https://blog.youkuaiyun.com/Tanswer_</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; Tanswer_]]></copyright><item><title><![CDATA[make 出现 OOM？？？]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/89515105</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/89515105</guid><author>Tanswer_</author><pubDate>Thu, 25 Apr 2019 14:13:09 +0800</pubDate><description><![CDATA[心情烦躁，随便翻翻博客，好久没更新了，来写篇水博，冷静一下。
这周编译一个项目的时候，出现 error，如下：

看到 cc1plus 被 killed 了，第一反应是不是因为 OOM killed 掉了，本来云服务器就只有 1G 内存。
用 dmesg 看一下吧，果然：

那怎么办，使用 swap 吧，需要开启一下，默认是关闭的。
使用交换文件来做交换分区。
// 先创建交换文件
falloca...]]></description><category></category></item><item><title><![CDATA[Linux 系统 CPU 使用率简单分析]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/85010131</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/85010131</guid><author>Tanswer_</author><pubDate>Fri, 14 Dec 2018 21:59:45 +0800</pubDate><description><![CDATA[CPU 使用率是单位时间内 CPU 使用情况的统计，以百分比的方式展示。
CPU 使用率
为了维护 CPU 时间，Linux 通过事先定义的节拍率（内核中表示为 HZ），触发时间中断，并使用全局变量 Jiffies 记录了开机一来的节拍数。每发生一次时间中断，Jiffies 的值就加 1。
Linux 通过 /proc 虚拟文件系统，向用户空间提供了系统内部状态的信息，而 /proc/stat 提...]]></description><category></category></item><item><title><![CDATA[Redis 客户端 Hiredis 简介]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/80848182</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/80848182</guid><author>Tanswer_</author><pubDate>Thu, 28 Jun 2018 21:03:07 +0800</pubDate><description><![CDATA[学习总结一下官方发布的C版本客户端 hiredis，了解hiredis 客户端大致实现细节。在理解代码之间需要了解通信协议的特点，我上一篇转载的文章已经有过介绍，大家可以去看一下。

hiredis 提供了同步、异步访问，异步 API 需要与一些事件库协同工作，主要看一下同步API的实现。

hiredis 与服务端通信的API比较简单，主要有这几个步骤：


建立连接
发送命令
等待结果并处理
...]]></description><category></category></item><item><title><![CDATA[Redis 通信协议（protocol）]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/80846757</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/80846757</guid><author>Tanswer_</author><pubDate>Thu, 28 Jun 2018 17:41:22 +0800</pubDate><description><![CDATA[本文档翻译自： http://redis.io/topics/protocol 。



Redis 协议在以下三个目标之间进行折中：


易于实现
可以高效地被计算机分析（parse）
可以很容易地被人类读懂




网络层

客户端和服务器通过 TCP 连接来进行数据交互， 服务器默认的端口号为 6379 。

客户端和服务器发送的命令或数据一律以 \r\n （CRLF）结尾。



请求

...]]></description><category></category></item><item><title><![CDATA[Linux交换空间（swap space）]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/80785783</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/80785783</guid><author>Tanswer_</author><pubDate>Sat, 23 Jun 2018 18:18:46 +0800</pubDate><description><![CDATA[每次安装Linux的时候，都会要求配置交换分区，那么这个分区是干嘛的呢？不设置这个分区有什么后果？如果一定要设置，设置多大比较合适？本篇将试图回答这些问题并尽量覆盖所有swap相关的知识。

下面的所有例子都在ubuntu-server-x86_64 16.04下执行通过



什么是swap?

swap space是磁盘上的一块区域，可以是一个分区，也可以是一个文件，或者是他们的组合。简单点说...]]></description><category></category></item><item><title><![CDATA[DNS协议详解及报文格式分析]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/80657756</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/80657756</guid><author>Tanswer_</author><pubDate>Mon, 11 Jun 2018 20:54:17 +0800</pubDate><description><![CDATA[DNS协议详解及报文格式分析]]></description><category></category></item><item><title><![CDATA[无锁队列的原理和实现]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/79677069</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/79677069</guid><author>Tanswer_</author><pubDate>Sat, 24 Mar 2018 13:20:09 +0800</pubDate><description><![CDATA[
无锁队列的实现-coolshell
CAS
另一篇参考
设计不使用互斥锁的并发数据结构
锁粒度
]]></description><category></category></item><item><title><![CDATA[复合&继承关系下的构造和析构]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/79217912</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/79217912</guid><author>Tanswer_</author><pubDate>Wed, 31 Jan 2018 16:25:55 +0800</pubDate><description><![CDATA[继承关系下的构造和析构

看一下测试代码：

/*
 * @filename:    Inheritance.cpp
 * @author:      Tanswer
 * @date:        2018年01月31日 14:59:28
 * @description: 测试继承关系下的构造和析构
 */

#include
using namespace std;

class Base]]></description><category></category></item><item><title><![CDATA[编写网络服务程序的常用编程模型]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/79157218</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/79157218</guid><author>Tanswer_</author><pubDate>Thu, 25 Jan 2018 02:32:20 +0800</pubDate><description><![CDATA[今天大概总结一下编写服务端程序常用的编程模型。参考UNP第三版第三十章和陈硕的muduo那本书，强烈建议仔细阅读。注意以下代码只是为了显式框架或者说编程模型，不是完整的程序，深夜写的比较任性，不要见怪。



accept + read/write

这个不是并发服务器，而是迭代服务器（iterative server）。 它一次服务一个客户。不适合长连接，适合 daytime 这种 write-]]></description><category></category></item><item><title><![CDATA[Muduo网络库源码分析之TcpConnection Class]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/79085406</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/79085406</guid><author>Tanswer_</author><pubDate>Wed, 17 Jan 2018 15:04:45 +0800</pubDate><description><![CDATA[用于管理一个具体的 TCP 连接，比如消息的接收与发送，完成用户指定的连接回调 connectionCallback。

TcpConnection 构造时接收参数有 TCP 连接的 sockfd，服务端地址 localAddr，客户端地址 peerAddr，并通过 Socket 封装 sockfd。并用 Channel 管理该 sockfd，向 Channel 注册可读、可写、关闭、出错回调函数]]></description><category></category></item><item><title><![CDATA[Muduo网络库源码分析之Acceptor和TcpServer]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/79048708</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/79048708</guid><author>Tanswer_</author><pubDate>Fri, 12 Jan 2018 22:43:03 +0800</pubDate><description><![CDATA[Acceptor

用于 accept 一个 TCP 连接，accept 接受成功后通知 TCP 连接的使用者。Acceptor 主要是供 TcpServer 使用的，其生命期由后者控制。一个 Acceptor 相当于持有服务端的一个 socket 描述符，该 socket 可以 accept 多个 TCP 客户连接，这个 accept 操作就是 Acceptor 实现的。

这里用到了一些封装好]]></description><category></category></item><item><title><![CDATA[C++智能指针的分析与使用]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/79039617</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/79039617</guid><author>Tanswer_</author><pubDate>Thu, 11 Jan 2018 23:39:30 +0800</pubDate><description><![CDATA[手动管理的弊端

在简单的程序中，我们不大可能忘记释放 new 出来的指针，但是随着程序规模的增大，我们忘了 delete 的概率也随之增大。在 C++ 中 new 出来的指针，赋值意味着引用的传递，当赋值运算符同时展现出“值拷贝”和“引用传递”两种截然不同的语义时，就很容易导致“内存泄漏”。

手动管理内存带来的更严重的问题是，内存究竟要由谁来分配和释放呢？指针的赋值将同一对象的引用散播到程序各]]></description><category></category></item><item><title><![CDATA[Muduo网络库源码分析之对socket及其相关操作的封装]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/79013180</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/79013180</guid><author>Tanswer_</author><pubDate>Tue, 09 Jan 2018 15:14:11 +0800</pubDate><description><![CDATA[主要涉及到的类和实现文件有：


Endian.h  
提供了字节序转换的函数。
Socket.h/Socket.cc 
socketfd 的封装，提供了绑定地址、开始listen、接受连接等操作，并可设置套接字选项。
InetAddress.h/InetAddress.cc 
套接字地址的封装，提供了多种方式初始化一个地址，还提供方法从地址中拿到 ip 和 port。
SocketsOps.h/]]></description><category></category></item><item><title><![CDATA[eventfd 的分析与具体例子]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/79008322</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/79008322</guid><author>Tanswer_</author><pubDate>Mon, 08 Jan 2018 23:22:55 +0800</pubDate><description><![CDATA[eventfd 介绍

Linux 2.6.27后添加了一个新的特性，就是eventfd，是用来实现多进程或多线程的之间的事件通知的。



接口

#include 
int eventfd(unsigned int initval, int flags);

这个函数会创建一个事件对象（eventfd object），返回一个文件描述符，用来实现进程或线程间的等待/通知（wait/notify]]></description><category></category></item><item><title><![CDATA[Muduo网络库源码分析之定时器的实现]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/78994879</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/78994879</guid><author>Tanswer_</author><pubDate>Sun, 07 Jan 2018 15:41:05 +0800</pubDate><description><![CDATA[muduo 的定时器功能由三个  class 实现，TimerId、Timer 和 TimerQueue。

TimerId 类

它唯一标识一个 Timer 定时器。TimerId Class 同时保存Timer* 和 sequence_，这个 sequence_ 是每个 Timer 对象有一个全局递增的序列号 int64_t sequence_，用原子计数器（AtomicInt64）生成。]]></description><category></category></item><item><title><![CDATA[Muduo网络库源码分析之Reactor模式的关键结构]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/78990738</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/78990738</guid><author>Tanswer_</author><pubDate>Sat, 06 Jan 2018 18:36:02 +0800</pubDate><description><![CDATA[本文分析一下Reactor模式的实现，关键是三个类：Channel、Poller、EventLoop。



事件分发类 Channel

Channel 是 selectable IO channel，负责注册与响应IO事件，包括注册给Poller的 fd 及其监听的事件，以及事件发生了所调的回调函数。 
每个Channel对象自始至终只负责一个 fd 的事件分发，封装了一系列该 fd 对应的操]]></description><category></category></item><item><title><![CDATA[FastCGI 协议分析与C语言实现实例]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/78879905</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/78879905</guid><author>Tanswer_</author><pubDate>Sat, 23 Dec 2017 14:46:54 +0800</pubDate><description><![CDATA[考虑让我的 web server 增加对 PHP 的支持，这就要用到 php 解析器来将客户端请求的 php 文件解析为静态资源，再由我的 web server 将其返回到客户端，php-fpm 就可以来帮我们完成这个工作。可是我的 web server 如何与 php-fpm 通信呢？ 接下来就是本文的主角：FastCGI 。FastCGI 实现与测试代码：https://github.com/T]]></description><category></category></item><item><title><![CDATA[内存管理之用户空间]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/78764778</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/78764778</guid><author>Tanswer_</author><pubDate>Sun, 10 Dec 2017 14:47:55 +0800</pubDate><description><![CDATA[32 位的平台上，线性地址空间为固定的 4GB，并且由于采用了保护机制，Linux内核将这 4GB 分为两部分，线性地址较高的 1GB（0xC0000000 到 0xFFFFFFFF ）为共享的内核空间；而较低的 3GB 为每个进程的用户空间。由于每个进程都不能直接访问内核空间，而是通过系统调用间接进入内核，因此所有的进程都共享内核空间。而每个进程都拥有各自的用户空间，各个进程之间不能互相访问彼此的]]></description><category></category></item><item><title><![CDATA[[编译链接装载]之静态链接]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/78730232</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/78730232</guid><author>Tanswer_</author><pubDate>Wed, 06 Dec 2017 15:38:25 +0800</pubDate><description><![CDATA[链接器之所以存在或者产生，基本上是由于程序开发的模块化。这里讲的模块，主要是编译概念上的模块，通常他们按照功能划分，比如一个.c或者.cpp文件就是一个编译单元，就是一个模块，编译后就产生一个.o目标文件。为了最终生成一个可执行文件、静态库或者动态库，就需要把各个编译单元按照特定的约定组合到一起。这里特定的约定指的就是“目标文件格式”，它定义了目标文件、库文件和可执行文件的格式，这里组合这一过程就叫]]></description><category></category></item><item><title><![CDATA[[编译链接装载系列]之聊聊目标文件与ELF格式]]></title><link>https://blog.youkuaiyun.com/Tanswer_/article/details/78713605</link><guid>https://blog.youkuaiyun.com/Tanswer_/article/details/78713605</guid><author>Tanswer_</author><pubDate>Mon, 04 Dec 2017 20:58:14 +0800</pubDate><description><![CDATA[编译器编译源代码后生成的文件叫做目标文件，从结构上讲它是已经编译后的可执行文件格式，只是还没有经过链接，其中可能有些符号或有些地址还没有调整。它本身就是按照可执行文件格式存储的，跟真正的可执行文件在结构上稍有不同。目标文件的格式：现在 PC 平台流行的可执行文件格式主要是 Windows 下的 PE（ Portable Executable，可移植可执行 ） 和 Linux 的 ELF（ Execu]]></description><category></category></item></channel></rss>