Intelligence without ambition is a bird without wings.

2016-03-23
glog

要点

  • 默认输出到/tmp/<program name>.<hostname>.<user name>.log.<severity level>.<date>.<time>.<pid>

  • FATAL和CHECK失败,会打印堆栈(默认打印到stderr),然后exit(1)

选项

  • minloglevel=NUM

    指定最小级别
    

命令行

  • 重定向到标准出错

    GLOG_logtostderr=1 ./your_application
    

参考

  1. https://google-glog.googlecode.com/svn/trunk/doc/glog.html
阅读此文

2016-03-23
util-linux

程序

  • /usr/bin/cal
  • /usr/bin/chfn
  • /usr/bin/chrt
  • /usr/bin/chsh
  • /usr/bin/col
  • /usr/bin/colcrt
  • /usr/bin/colrm
  • /usr/bin/column
  • /usr/bin/dmesg
  • /usr/bin/eject
  • /usr/bin/fallocate
  • /usr/bin/findmnt
  • /usr/bin/flock
  • /usr/bin/getopt
  • /usr/bin/hexdump
  • /usr/bin/i386
  • /usr/bin/ionice
  • /usr/bin/ipcmk
  • /usr/bin/ipcrm
  • /usr/bin/ipcs
  • /usr/bin/isosize
  • /usr/bin/kill
  • /usr/bin/linux32
  • /usr/bin/linux64
  • /usr/bin/logger
  • /usr/bin/login
  • /usr/bin/look
  • /usr/bin/lsblk
  • /usr/bin/lscpu
  • /usr/bin/lslocks
  • /usr/bin/lslogins
  • /usr/bin/mcookie
  • /usr/bin/more
  • /usr/bin/mount
  • /usr/bin/mountpoint
  • /usr/bin/namei
  • /usr/bin/nsenter
  • /usr/bin/prlimit
  • /usr/bin/raw
  • /usr/bin/rename
  • /usr/bin/renice
  • /usr/bin/rev
  • /usr/bin/script
  • /usr/bin/scriptreplay
  • /usr/bin/setarch
  • /usr/bin/setpriv
  • /usr/bin/setsid
  • /usr/bin/setterm
  • /usr/bin/su
  • /usr/bin/tailf
  • /usr/bin/taskset
  • /usr/bin/ul
  • /usr/bin/umount
  • /usr/bin/unshare
  • /usr/bin/utmpdump
  • /usr/bin/uuidgen
  • /usr/bin/wdctl
  • /usr/bin/whereis
  • /usr/bin/write
  • /usr/bin/x86_64
  • /usr/sbin/addpart
  • /usr/sbin/agetty
  • /usr/sbin/blkdiscard
  • /usr/sbin/blkid
  • /usr/sbin/blockdev
  • /usr/sbin/cfdisk
  • /usr/sbin/chcpu
  • /usr/sbin/clock
  • /usr/sbin/ctrlaltdel
  • /usr/sbin/delpart
  • /usr/sbin/fdformat
  • /usr/sbin/fdisk
  • /usr/sbin/findfs
  • /usr/sbin/fsck
  • /usr/sbin/fsck.cramfs
  • /usr/sbin/fsck.minix
  • /usr/sbin/fsfreeze
  • /usr/sbin/fstrim
  • /usr/sbin/hwclock
  • /usr/sbin/ldattach
  • /usr/sbin/losetup
  • /usr/sbin/mkfs
  • /usr/sbin/mkfs.cramfs
  • /usr/sbin/mkfs.minix
  • /usr/sbin/mkswap
  • /usr/sbin/nologin
  • /usr/sbin/partx
  • /usr/sbin/pivot_root
  • /usr/sbin/readprofile
  • /usr/sbin/resizepart
  • /usr/sbin/rtcwake
  • /usr/sbin/runuser
  • /usr/sbin/sfdisk
  • /usr/sbin/sulogin
  • /usr/sbin/swaplabel
  • /usr/sbin/swapoff
  • /usr/sbin/swapon
  • /usr/sbin/switch_root
  • /usr/sbin/wipefs
阅读此文

2016-03-23
procps-ng

查询命令

rpm -ql procps-ng |grep bin

程序

  • /usr/bin/free
  • /usr/bin/pgrep
  • /usr/bin/pkill
  • /usr/bin/pmap
  • /usr/bin/ps
  • /usr/bin/pwdx
  • /usr/bin/skill
  • /usr/bin/slabtop
  • /usr/bin/snice
  • /usr/bin/tload
  • /usr/bin/top
  • /usr/bin/uptime
  • /usr/bin/vmstat
  • /usr/bin/w
  • /usr/bin/watch
  • /usr/sbin/sysctl
阅读此文

2016-03-23
pstree

选项

  • -a

    输出进程的命令行参数

  • -p

    输出进程PID

  • -u

    输出进程使用者

  • -s

    Show parent processes of the specified process.

  • -n

    按PID排序

  • -l

    完整显示,默认80列

  • -h

    高亮当前进程及其父进程

  • -H PID

    高亮PID进程及其父进程

实例

  • 显示PID进程的族谱

    pstree -apls PID
    
阅读此文

2016-03-19
linux头文件组织

通过yum provides FILENAME来查找所属包

  • glibc-headers(使用C开发库,必须安装的包)

    /usr/include/sys/usr/include/bits

  • kernel-headers(被glibc使用)

    /usr/include/linux/usr/include/asm

阅读此文

2016-03-19
rpm

  • 查询包信息

    rpm -q glibc
    
  • 列出包文件

    rpm -ql glibc
    
阅读此文

2016-03-19
yum

  • 查询文件所属

    yum provides /usr/include/sys/types.h
    
  • 下载包

    yum -y install yum-utils
    yumdownloader httpd
    
阅读此文

2016-03-18
protobuf

优缺点

  • 二进制编码,格式紧凑,编解码快,占用内存小

  • 可读性非常差,不利于调试

命令

protoc [OPTION] PROTO_FILES

基本用法

  • 输出c++代码

    protoc --cpp_out=. base.proto
    

API

  • 基本类型(uint32string等)提供了set_方法

  • singular(单数) message字段(自定义消息),提供mutalbe_方法设置值,没有set_方法

  • repeated字段

    • _size查询数量
    • 下标访问(获取,修改)
    • add_添加(返回指针来修改数据)

编码风格(https://developers.google.com/protocol-buffers/docs/style)

  • 消息类型

    CamelCase(with an initial capital)

  • 字段

    underscore_separated_names

1
2
3
4
5
6
7
8
9
10
11
message SongServerRequest {
required string song_name = 1;
}

C++:
const string& song_name() { ... }
void set_song_name(const string& x) { ... }

Java:
public String getSongName() { ... }
public Builder setSongName(String v) { ... }
  • 枚举

    Use CamelCase (with an initial capital) for enum type names and CAPITALS_WITH_UNDERSCORES for value names

1
2
3
4
enum Foo {
FIRST_VALUE = 1;
SECOND_VALUE = 2;
}
  • service

    CamelCase (with an initial capital) for both the service name and any RPC method names

1
2
3
service FooService {
rpc GetSomething(FooRequest) returns (FooResponse);
}

编码原理(https://developers.google.com/protocol-buffers/docs/encoding)

消息结构

Varint

采用类似于UTF-8编码方式,来编码整型数,该数为uint64类型,负数采用补码,所以占用8B,对应需要10B(ceil((8 * 8) / 7))

  • 每个字节用7bits来编码数字

  • 单字节的最高位(Most Significant Bit),来表示是否还有后续字节(1表示有,0表示没有)。

  • 多字节数采用小端字节序

1
2
3
1 => 0000 0001
150(1001 0110) => 10010110 00000001
300(0000 0001 0010 1100) => 1010 1100 0000 0010

源码(encode.go):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const maxVarintBytes = 10 // maximum length of a varint

// EncodeVarint returns the varint encoding of x.
// This is the format for the
// int32, int64, uint32, uint64, bool, and enum
// protocol buffer types.
// Not used by the package itself, but helpful to clients
// wishing to use the same encoding.
func EncodeVarint(x uint64) []byte {
var buf [maxVarintBytes]byte
var n int
for n = 0; x > 127; n++ {
buf[n] = 0x80 | uint8(x&0x7F)
x >>= 7
}
buf[n] = uint8(x)
n++
return buf[0:n]
}

具体有key(tag+type)lengthvalue(int32, int64, uint32, uint64, sint32, sint64, bool, enum)使用varint编码。

参考

  1. https://www.ibm.com/developerworks/cn/linux/l-cn-gpb/
阅读此文

2016-03-15
epoll

API

1
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

返回值

  • 0 返回IO就绪的文件描述符总数;

  • ==0 超时返回

  • <0(-1) 出错(需要注意,该调用为慢速系统调用,当被信号中断时,返回EINTR)

原理

调用epoll_create时,内核除了帮我们在epoll文件系统里建了个file结点,在内核cache里建了个红黑树用于存储以后epoll_ctl传来的fd外,还会再建立一个list链表,用于存储准备就绪的事件,当epoll_wait调用时,仅仅观察这个list链表里有没有数据即可。有数据就返回,没有数据就sleep,等到timeout时间到后即使链表没数据也返回。所以,epoll_wait非常高效。而且,通常情况下即使我们要监控百万计的fd,大多一次也只返回很少量的准备就绪fd而已,所以,epoll_wait仅需要从内核态copy少量的fd到用户态而已。那么,这个准备就绪list链表是怎么维护的呢?当我们执行epoll_ctl时,除了把fd放到epoll文件系统里file对象对应的红黑树上之外,还会给内核中断处理程序注册一个回调函数,告诉内核,如果这个fd的中断到了,就把它放到准备就绪list链表里。所以,当一个fd(例如socket)上有数据到了,内核在把设备(例如网卡)上的数据copy到内核中后就来把fd(socket)插入到准备就绪list链表里了

工作流程

  1. 执行epoll_create时,创建了红黑树和就绪list链表。

  2. 执行epoll_ctl时,如果增加fd(socket),则检查在红黑树中是否存在,存在立即返回,不存在则添加到红黑树上,然后向内核注册回调函数,用于当中断事件来临时向准备就绪list链表中插入数据。

  3. 执行epoll_wait时立刻返回准备就绪链表里的数据

要点

  • epoll_event中的epoll_data_t用来存储用户自定义数据

    当与其绑定的fd上发生指定的事件时,epoll_wait返回该event,用户可以拿到该数据

为什么高效(相对selectpoll)?

  • 无需每次调用,都将套接字集合从应用层拷贝到内核层。

    epoll采用红黑树来管理描述符,epoll_ctl执行管理操作

  • 当有IO事件返回时,epoll无需遍历整个描述符集合(O(m),m为IO就绪的数量),而select/poll则是O(n),大大的减少了轮询操作

    epoll返回event的集合(该event结构包含用户数据),应用层只需根据原有数据来分发事件

  • 内核采用slab算法管理epoll相关数据结构,加速了相关操作时间

阅读此文

2016-03-11
tcp-read

ssize_t read(int fildes, void *buf, size_t nbyte);

返回值

  • 0,成功读取了n字节

  • =0,对方断开了连接

  • <0,发生了错误

    • EINTR 被中断,没有读取到数据
阅读此文